我在一个更大的项目中遇到了这个问题所以我做了一个测试课,希望能识别并解决它:
class test_class{
public:
int length;
const char* cstr;
test_class(){cstr = nullptr; length = 0;}
void SetStr(string str){cstr = str.c_str(); length = str.length();}
};
因此,当我使用SetStr
成员函数时,cstr
中的第一个字符就像一个空终止符。以下代码是一个示例:
string str5="abcdefg";
test_class test;
test.SetStr(str5);
cout<<test.cstr<<endl;
cout
不输出任何内容,但第一个后的字符有效。因此,如果我用循环打印它们,除了第一个字符外,我得到整个字符串。
但如果我按如下方式重写SetStr
函数(添加&
):
void SetStr(string& str){cstr = str.c_str(); length = str.length();}
工作正常。
问题:
我不明白没有&
的函数有什么问题,它是如何解决这个问题的呢?
答案 0 :(得分:1)
区别在于哪个对象拥有cstr
指向的数据。
string str5="abcdefg";
test_class test;
test.SetStr(str5);
cout<<test.cstr<<endl;
当您通过引用传递时,SetStr
直接从str5
检索指针 - str5
拥有数据,只要str5
存在,指针就会保持有效。<登记/>
由于str5
在您打印test.cstr
时仍然存在,所以一切都很好。
当您按值传递时,数据由参数拥有,该参数是str5
的副本
由于参数对象在函数返回时被销毁,之后指向其数据的指针无效,并且取消引用它是未定义的。