为什么自动从const转换为非const&设置班级成员时会发生什么?

时间:2016-03-01 09:00:34

标签: c++ oop

以下代码编译并运行。为什么它不会产生错误:"无法转换为' 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!"

2 个答案:

答案 0 :(得分:5)

您会混淆initializationassignment

_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"