当我尝试编译下面的源代码时出现以下错误。任何人都可以描述为什么会出现这个错误以及如何解决它?
错误1错误C2758:'A :: s_':必须在构造函数base / member initializer中初始化
#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;
}
答案 0 :(得分:8)
首先,您的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
构造函数结束时,它的生命周期是延长还是 die ?你确定你需要的是参考吗?
std::string s("hello world");
int main()
{
// New A instance:
A a(s);
return 0;
}
使用上面的代码,创建一个新的A
实例,调用相同的A::A(string& s)
构造函数,但提供的字符串位于全局范围内,因此不会销毁它{{{}来自A::s_
实例的1}}将在其生命周期内引用有效字符串,但真正的威胁在复制构造函数中:
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;
}
!这就是你想要的吗?
答案 1 :(得分:2)
您的复制构造函数从不初始化引用。确保它确实:
A(const A &rhs) : s_(rhs.s_) {cout << "A::copy" << endl;}
答案 2 :(得分:0)
string& s_;
这是一个参考变量。当对象被分配时它应该有一个值,因为这是对象的一部分,这就是为什么应该使用构造函数的初始化列表来初始化这个属性。
如果您不需要像对象的一部分那样拥有此属性,则可以使用指针而不是referance:
string* s_;