题
我有一个类,其构造函数对字符串进行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的一些实现可以在场景后面执行此操作,但不是必需的。你不应该依赖这个。