まず第一に、あなたA::s_
はstd::string
;への参照です。つまり、どこかに存在しなければならない何かを参照しているということです。
彼の参照型と、参照が作成された時点で初期化する必要があるという事実のためにA::s_
、すべてのA
コンストラクターで初期化する必要があります(他のユーザーが指摘しているように)。
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
ます。それはあなたが望むものですか?