我有以下代码:
struct Y {
string& s1; //string s1; throws no error
Y( string src ) : s1(src) { cout<<"s1: "<<s1<<endl; }
void show(){ cout<<s1<<endl; }
};
int main()
{
Y y1("Krypton");
y1.show(); //run-time error
}
y1.show(( 应该显示"氪",但我收到运行时错误(由于调用 y1.show(( 时 s1 未初始化?
问题 1.当 s1 已经在构造函数初始化列表中初始化时,为什么它会未初始化?问题 2.如果我使用字符串 s1,为什么我不会得到同样的错误;而不是参考?
任何帮助将不胜感激。
问候
杰。
您正在从临时初始化引用。如果希望 struct Y
实例保存实际字符串,而不仅仅是引用,则需要字符串类型的成员变量,而不是对字符串的引用。
问题 1.当 s1 已经在构造函数初始化列表中初始化时,为什么它会未初始化?
它已初始化,但作为对不再存在的字符串的引用。
问题 2.如果我使用字符串 s1,为什么我不会得到同样的错误;而不是参考?
如果类包含字符串,则它不包含对现有字符串的引用。
您认为引用是引用的字符串?
s1
被设置为引用src
,这是一个临时对象,当构造函数存在时被销毁。
当您将s1
设置为字符串时,它是一个不依赖于src
的本地副本
因为你的构造函数Y(string src)
接受一个模板值,并且s1
引用这个模板值,然后你调用show()
打印的值女巫在构造函数之后是destroty。
答:
1.因为引用的值s1
构造函数后销毁。
2.如果使用string s1
而不是string& s1
,则在调用构造函数时分配src
yo s1,show()
将打印s1的成员值。
如果你想撬"氪",你可以Y( string src )
改为Y( string& src )
在您的情况下,您可以像这样初始化临时成员变量
struct Y
{
string& s1;
Y( string& src )
: s1(src)
{
cout<<"s1: "<<s1<<endl;
}
void show()
{
cout<<s1<<endl;
}
};
int main()
{
string s1_real = "Krypton";
Y y1(s1_real);
y1.show();
return 0;
}
请注意,
构造函数接受引用(string&src not string src(。因为如果你使用"string src",它将是一个临时变量,一旦函数堆栈展开并且 s1 最终成为一个悬空引用,它就会被销毁。如果使用"string&src",则不会创建新的内存位置;SRC 指向 s1_real,因此 S1 最终指向 s1_real。
创建一个用于创建 y1 的变量 (s1_real(。这是因为你不能引用临时变量(你只能引用 const 引用,在这种情况下,src 和 s1 也必须声明为 const 引用(
始终注意 y1 的寿命必须小于 s1_real 的寿命,否则 y1.s1 最终会成为悬空的参考