首先,你A::s_
是一個std::string
參考;這意味着它引用了某個地方必須存在的東西。
由於他引用類型的,而事實上,引用必須在他們所創建的那一刻被初始化,你必須在所有的A
構造函數初始化A::s_
(由其他用戶指出):
class A
{
public:
A(string& s) : s_(s)
{ cout << "A::ctor" << endl; }
A(const A& rhs) : s_(rhs.s_) // <-- here too!!
{ cout << "A::copy" << endl; }
~A()
{ cout << "A::dtor" << endl; }
A& operator=(const A& rhs)
{ cout << "A::copyassign" << endl; }
private:
string& s_;
};
現在回到我剛纔提到的第一件事。在A::s_
必須參考的東西存在,所以你必須知道的一些事情,看看下面的代碼:
int main()
{
// New A instance:
A a("hello world");
return 0;
}
構建這個A
情況下,我們要提供一個const char[12]
值,這個值暫時std::string
被創建並被賦予A::A(string& s)
構造函數。 A::s_
在構造函數結束後引用的位置?創建臨時std::string
會發生什麼?它的使用壽命是延長還是隻有當A
構造函數結束時死亡?你確定參考是你需要的嗎?
std::string s("hello world");
int main()
{
// New A instance:
A a(s);
return 0;
}
通過上面的代碼,創建一個新的A
實例調用相同A::A(string& s)
構造函數,但提供的字符串趴在全球範圍內,所以也沒有被破壞,A::s_
從a
實例將引用一個有效的字符串的所有生命週期,但真正的威脅是拷貝構造函數:
std::string s("hello world");
int main()
{
A a(s); // a.s_ references the global s.
A b(a); // b.s_ references the a.s_ that references the global s.
return 0;
}
複製的對象值將引用給定對象的std::string
!那是你要的嗎?
當你有一個引用成員時,你不能真正擁有一個語義上有效的賦值運算符。您不能將其重新分配給不同的字符串。它只會修改被引用的原始字符串。 –