以下代码编译并运行。为什么它不会产生错误:"无法转换为' const std :: string'到' std :: string&'"?
class Test {
private:
std::string& _str;
public:
Test(std::string& str) : _str(str)
{ }
void SetStr(const std::string& str)
{
// std::string& s = str; // error: cannot convert from 'const std::string' to 'std::string &'
_str = str; // strange, but it works!
_str.append(", world!"); // it works too
}
const std::string& GetStr()
{
return _str;
}
};
...
std::string str = "";
Test test(str);
test.SetStr("Hello");
std::cout << test.GetStr(); // prints "Hello, world!"
std::cout << str; // also prints "Hello, world!"
答案 0 :(得分:5)
您会混淆initialization和assignment。
_str = str;
是一项任务,std::string::operator=(const std::string&)
将被调用,str
可以作为参数。这意味着绑定的对象_str
的值将被更改,而不是引用本身。出于同样的原因,_str.append(", world!");
也很好。
虽然std::string& s = str;
是引用初始化,但它失败了,因为无法将const绑定到非const引用。
答案 1 :(得分:1)
初始化参考后,它始终引用已初始化的对象,您无法重新分配参考变量。
当您在_str = str
函数中执行作业SetStr
时,您不会更改引用,而是更改它引用的对象,这不是常量对象。
简单示例:
std::string string1 = "foo";
std::string const string2 = "bar";
std::string& string_ref = string1; // string_ref now is a reference of string1
string_ref = string2; // Doesn't change what string_ref references,
// instead changes string1
std::cout << string1 << '\n'; // Will output "bar"