返回字符串引用是下面的最佳案例

Che*_*eng 1 c++

假设我正在设计一个接口,以返回子类的名称.请注意,对于子类的不同实例,它们的名称应保持不变.

为了提高速度和内存效率,我想说第三种方法签名可能是最好的(根据char*vs cd中的std :: string的一些注释)

virtual const std::string& name2() const = 0;
Run Code Online (Sandbox Code Playgroud)

我想知道有更好的选择吗?

#include <cstdio>
#include <string>

class baby_interface {
public:
    virtual const char* name0() const = 0;
    virtual std::string name1() const = 0;
    virtual const std::string& name2() const = 0;
};

class baby : public baby_interface {
public:
    virtual const char* name0() const
    {
        return "My Baby";
    }

    virtual std::string name1() const
    {
        return "My Baby";
    }

    virtual const std::string& name2() const
    {
        return std::string("My Baby");
    }
};

int main()
{
    baby b;

    // Refer to same char array address.
    printf("%x\n", b.name0());
    printf("%x\n\n", b.name0());

    // Refer to different char array address.
    printf("%x\n", b.name1().c_str());
    printf("%x\n\n", b.name1().c_str());

    // Refer to same char array address.
    printf("%x\n", b.name2().c_str());
    printf("%x\n\n", b.name2().c_str());
    getchar();
}
Run Code Online (Sandbox Code Playgroud)

GMa*_*ckG 8

如果你正确地做的话可以.你现在拥有的是未定义的:

virtual const std::string& name2() const
{
    return std::string("My Baby"); // constructs temporary string!
}
Run Code Online (Sandbox Code Playgroud)

您将返回对临时的引用.为此,它必须是l值.你可以把它变成静态的:

virtual const std::string& name2() const
{
    static const std::string result = "My Baby";
    return result;
}
Run Code Online (Sandbox Code Playgroud)

或者类的成员等.现在它返回一个可用的变量.

我对常见的事情没有多少经验,但我猜如果在模块之间使用这些接口,第一个是常见的.(即,从共享库/ dll分配的接口).这是因为编译器之间的字符串实现可能不同,有时甚至是同一编译器的不同版本.如果程序是用一个实现创建的,而派生的是在另一个实现中,则在两者之间进行转换可能会失败.

通过使用const char *(在所有编译器中都是相同的),您可以避免这种情况.但是,const char *有些人看起来不雅观.

第二个选项似乎是我会使用的,因为强制派生类创建一个静态/ l值变量可能不是你应该做的.无论如何,副本可能非常快.