是自我初始化'A a = a;'允许?

时间:2009-06-11 15:10:53

标签: c++

此代码在运行时在复制构造函数中失败 但是编译器(MSVS2008)没有发出警告。

你能解释(最好引用标准)这段代码是非法的还是什么?

我明白A a = a;永远不应该写在第一个地方, 但我正在寻找理论背景。

 class A
 {
 public: 

    A()
    :p(new int)
    {
    }

    A(const A& rv)
    {
        p = new int(*rv.p);
    }

    ~A()
    {
        delete p;
    }


 private:

    int *p;
 };

 int main()
 {
    A a = a;
 }

4 个答案:

答案 0 :(得分:8)

您的代码不是调用标准构造函数而是调用复制构造函数,因此您正在访问未初始化的指针。

答案 1 :(得分:4)

关于自我指派的有趣读物:http://www.gotw.ca/gotw/011.htm

特别注意与此问题相关的“Postscript#1”以及给出的一些答案。

答案 2 :(得分:3)

根据标准(12.6.1 [class.expl.init]),自我初始化是完全合法的。

因此以下是合法的。

A a = a;

您只需编写复制构造函数即可正确处理它。

A(const A& rv)
{
    if(&rv == this) {
        p = new int(0);
        return;
    }

    p = new int(*rv.p);
}

编辑:根据评论更新了代码。

答案 3 :(得分:1)

绝对不应该写

A a = a;。但是可以写a = a。您的赋值运算符必须检查&rv == this,并且在自我复制的情况下不执行任何操作。

哦,是的,您确实需要为A类编写赋值运算符。