The source variable with the error must be initialized in the base / member initializer of the constructor

I got the following error when I try to compile the source code below. Can someone describe why this error exists and how can I fix it?

Error 1 Error C2758: "A :: s_": must be initialized in the initializer of the constructor / member base

#include <iostream> #include <string> using namespace std; class A { public: A(string& s) : s_(s) { cout << "A::ctor" << endl; } A(const A& rhs) { cout << "A::copy" << endl; } ~A() { cout << "A::dtor" << endl; } A& operator=(const A& rhs) { cout << "A::copyassign" << endl; } private: string& s_; }; int main() { return 0; } 
+3
source share
3 answers

First of all, your A::s_ is a reference to std::string ; this means that he refers to something that must exist somewhere.

Due to its reference type and the fact that links must be initialized at the time of their creation, you must initialize A::s_ in all A constructors (as indicated 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, to the first that I mentioned; A::s_ should refer to something existing, so you should know about some things, look at the following code:

 int main() { // New A instance: A a("hello world"); return 0; } 

Creating this instance of A , we provide the value const char[12] , with this value a temporary std::string and assigned to the constructor A::A(string& s) . Where is A::s_ referenced after the constructor completes? What happens to the created temporary std::string ? Is this lifetime extended or does it just die when constructor A ends? Are you sure you need a link?

 std::string s("hello world"); int main() { // New A instance: A a(s); return 0; } 

Using the above code, a new instance of A , calling the same constructor A::A(string& s) , but with the provided string lying in the global scope, so it is not destroyed and the A::s_ from A instance refers to a valid string for life, but the real threat lies 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 value of the object will refer to the std::string this object! Is this what you want?

+7
source

The copy constructor never initializes the link. Make sure it:

 A(const A &rhs) : s_(rhs.s_) {cout << "A::copy" << endl;} 
+2
source
  string& s_; 

This is a referance variable. It should matter when the object is allocated, because it is part of the object, so you should use the constructor initialization list to initialize this attribute.

If you do not need to have this attribute as part of an object, you can use a pointer instead of a link:

  string* s_; 
0
source

Source: https://habr.com/ru/post/1484111/


All Articles