2016-03-01 16 views
3

下面的代碼編譯和工作。爲什麼不產生錯誤:「不能從'const std :: string'轉換爲'std :: string &'」?爲什麼在設置類成員時自動從const轉換爲非const&發生?

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

回答

5

你混淆initializationassignment

_str = str;是一個轉讓,std::string::operator=(const std::string&)將被調用,str是罰款作爲參數。這意味着被綁定的對象_str的值將被改變,而不是參考本身。出於同樣的原因_str.append(", world!");也很好。

雖然std::string& s = str;是一個引用初始化,但它失敗了,因爲無法將const綁定到非const引用。

1

一旦引用被初始化,它總是引用它已被初始化的對象,你不能重新分配引用變量。

當您在SetStr函數中執行賦值_str = str時,您不會更改引用,而是更改其引用的對象,該對象不是常量對象。


簡單的例子:

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" 
相關問題