必须在构造函数base/member初始化程序中初始化带错误的引用变量

Num*_*r42 5 c++ constructor compiler-errors visual-studio-2012

当我尝试编译下面的源代码时出现以下错误.任何人都可以描述为什么会出现此错误以及如何解决此问题?

错误1错误C2758:'A :: s_':必须在构造函数base/member初始化程序中初始化

#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;
}
Run Code Online (Sandbox Code Playgroud)

Pap*_*ter 9

首先,你A::s_是对a的引用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_;    
};
Run Code Online (Sandbox Code Playgroud)

现在,回到我提到的第一件事; 在A::s_必须引用的东西存在,所以你必须知道的一些事情,看看下面的代码:

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

构造这个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;
}
Run Code Online (Sandbox Code Playgroud)

通过上面的代码,新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;
}
Run Code Online (Sandbox Code Playgroud)

复制的对象值将引用std::string给定对象的值!那是你要的吗?