我有一个类,其构造函数对字符串进行const引用。此字符串充当对象的名称,因此在类的实例的整个生命周期中都需要。

现在想象一下如何使用这个类:

class myclass {
public:
    myclass(const std::string& _name) : name(_name) {}
private:
    std::string name;
};

myclass* proc() {
    std::string str("hello");
    myclass* instance = new myclass(str);
    //...
    return instance;
}

int main() {
    myclass* inst = proc();
    //...
    delete inst;
    return 0;
}

由于proc()中的字符串是在堆栈上创建的,因此在proc()完成时被删除, 我在类实例中引用它会发生什么?我的猜测是它变得无效。我最好在课堂上保留一份副本吗?我只是想避免任何不必要的复制像字符串......这样的潜在大对象。

有帮助吗?

解决方案

是的,在您的情况下,参考无效。由于您使用的是字符串,因此最好在 myclass 类中保留字符串对象的副本。

其他提示

一定要:复制。有一个“std :: string name”你班上的成员。这是控制生命周期的唯一方法。

如果myclass :: _ name不是引用,则复制它并且不会变为无效。

您无需复制。在 myclass 中声明 std :: string name (非引用)成员(你以某种方式完全省略了它)。并传递 const char * 作为参数。这样你就可以在类中构造你的名字对象而不需要复制。

class myclass {
public:
    std::string name;
    myclass(const char *_name) : name(_name) { }
};

myclass *proc() {
    return new myclass("hello");
}

是的,std :: string会消失,但是c str“你好”不会因为它是常数。

你有两个可能的答案。使用c str作为参考或使std:string成为staic。

字段myclass :: name应为std :: string类型。 C ++中的字符串是写时复制的( http://en.wikipedia.org/ wiki /写时复制)因此您不会遇到复制大对象的问题。

在MyClass中保留字符串的副本,保持引用最终安全。如果您希望很多实例具有相同的名称,您应该查看 Flyweight设计模式当你有很多相同的实例时,它允许节省存储空间。 Boost.Flyweight 是一个非常方便的实施这种模式允许你简单地写:

class myclass {
public:
    myclass(const std::string& _name) : name(_name) {}
private:
    boost::flyweight<std::string> name;
};

std :: string的一些实现可以在场景后面执行此操作,但不是必需的。你不应该依赖这个。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top