5

当我尝试编译下面的源代码时出现以下错误。任何人都可以描述为什么存在这个错误以及我该如何解决它?

错误 1 ​​错误 C2758: 'A::s_' : 必须在构造函数基/成员初始化程序中初始化

#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;
}
4

3 回答 3

10

首先, yourA::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_;    
};

现在,回到我提到的第一件事;必须引用存在的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_froma实例将在其整个生命周期中引用一个有效的字符串,但真正的威胁在复制构造函数中:

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给定对象的值!那是你要的吗?

于 2012-10-15T07:56:55.000 回答
2

您的复制构造函数从不初始化引用。确保这样做:

A(const A &rhs) : s_(rhs.s_) {cout << "A::copy" << endl;}
于 2012-10-15T06:39:41.287 回答
0
 string& s_;

这是一个参考变量。当对象被分配时它应该有一个值,因为这是对象的一部分,这就是为什么应该使用构造函数的初始化列表来初始化这个属性。

如果您不需要将此属性作为对象的一部分,则可以使用指针而不是引用:

 string* s_;
于 2012-10-15T06:42:05.720 回答