我有一个类,其构造函数对字符串进行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()完成时被删除, 我在类实例中引用它会发生什么?我的猜测是它变得无效。我最好在课堂上保留一份副本吗?我只是想避免任何不必要的复制像字符串......这样的潜在大对象。
答案 0 :(得分:8)
是的,在您的情况下,参考无效。由于您使用的是字符串,因此最好在myclass
类中保留字符串对象的副本。
答案 1 :(得分:3)
一定要:复制。在您的班级中有一个“std :: string name”成员。这是控制生命周期的唯一方法。
答案 2 :(得分:1)
如果myclass :: _ name不是引用,则复制它并且不会变为无效。
答案 3 :(得分:1)
您无需复制。在std::string name
中声明myclass
(非引用)成员(您以某种方式完全省略了)。并传递const char *
作为参数。这样你就可以在类中构造你的名字对象而不需要复制。
class myclass {
public:
std::string name;
myclass(const char *_name) : name(_name) { }
};
myclass *proc() {
return new myclass("hello");
}
答案 4 :(得分:1)
是的,std :: string会消失,但是c str“hello”不会,因为它是一个常量。
你有两个可能的答案。使用c str作为参考或使std:string成为staic。
答案 5 :(得分:0)
字段myclass :: name应为std :: string类型。 C ++中的字符串是写入时复制的(http://en.wikipedia.org/wiki/Copy-on-write),因此您不会遇到复制大对象的问题。
答案 6 :(得分:0)
在MyClass中保留字符串的副本,保持引用最终不安全。如果您希望很多实例具有相同的名称,那么您应该查看Flyweight design pattern,它允许在有大量相等实例时保存存储。 Boost.Flyweight是这种模式的非常有效的实现,允许您简单地写:
class myclass {
public:
myclass(const std::string& _name) : name(_name) {}
private:
boost::flyweight<std::string> name;
};
std :: string的一些实现可以在场景后面执行此操作,但不是必需的。你不应该依赖这个。