First of all, your A::s_
is a reference to a std::string
; that means that it's referencing something that must exists somewhere.
Due of his reference type, and the fact that the references must be initialized at the moment they're created, you must initialize A::s_
in ALL the A
constructors (as pointed by other users):
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_;
};
And now, back to the first thing I mentioned; the A::s_
must reference something that exists, so you must be aware of some things, take a look at the following code:
int main()
{
// New A instance:
A a("hello world");
return 0;
}
Constructing this A
instance we're providing a const char[12]
value, with this value a temporary std::string
is created and is given to the A::A(string& s)
constructor. Where A::s_
is referencing after the constructor ends? What happens with the temporary std::string
created? It's lifetime is extended or it just die when the A
constructor ends? Are you sure that a reference is what you need?
std::string s("hello world");
int main()
{
// New A instance:
A a(s);
return 0;
}
With the code above, a new A
instance is created calling the same A::A(string& s)
constructor, but with a provided string lying in the global scope, so it doesn't be destroyed and the A::s_
from the a
instance would reference a valid string all its lifetime, but the real threat is in the copy constructor:
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;
}
The copied object value will reference the std::string
of the given object! Is that what you want?