在C ++中初始化为自身的对象

时间:2015-08-01 06:57:13

标签: c++ class object initialization self

例如,我有代码:

class test{
    public:

    test(){
        cout<<endl<<"TEST";
    }

    void another(){
        cout<<endl<<"Another";
    }

};

int main(){
    test chk = chk;
    chk.another();
}

在这里,我已经将新创建的test类型的对象初始化为自身。

这种初始化是否有特殊用途,除了初始化test chk;而不是test chk = chk;之外,这种初始化是否会做任何事情?

据我所知,如果对象初始化为自身,则无法调用构造函数,但为什么?

我想了解更多有关对象自身初始化的信息。

2 个答案:

答案 0 :(得分:5)

你可以写:

test chk = chk;

[basic.scope.declarative] / P1

  

第一个j的潜在范围在j

之后立即开始

因此调用implicit copy constructor。您可能已经使用自己的方法执行了一些额外的初始化:

test(const test&) {
  cout << endl << "copy ctor";
}

请注意,这不是一种好的做法,在某些情况下甚至可能导致undefined behavior,并且Clang始终会发出-Wuninitialized警告。

答案 1 :(得分:1)

我稍微修改了你的代码,希望你能抓住这一点:

class test{
    public:
        test(){ cout<<endl<<"TEST"; }

        test(const test& in)
        {   
            if ( this == &in)
            {   
                cout<<endl<<"Self init";
            }
            cout<<endl<<"Copy ctor";
        }

        void another(){ cout<<endl<<"Another"; }
};  

int main(){
    test chk = chk;
    chk.another();
    cout<<endl;
}  

如果您现在调用代码,您将获得以下输出:

Self init
Copy ctor
Another

cout<<endl语句的一句话。您最后一次输出是隐藏的,因为在最后一次输出后没有endlcout是缓冲的,这意味着它只会在下一个endl或缓冲区已满后写入您的控制台。所以最好写一下:cout<<"something"<<endl;

代码和init:

如果您在复制构造函数中获取输入对象的地址,则可以检查是否对自己进行了复制。这是一种很好的做法,因为如果你已经分配了无法用默认构造函数复制的内存,你需要一个自己的复制构造函数。从我的示例中可以看出,thisin的地址是相同的,这意味着复制构造函数想要复制到自身,如果不以特殊方式处理,这通常是错误的!

对于您的测试用例,行为只是您的对象未初始化,因为您将未初始化的对象复制到自身,最终在未初始化的对象中。这绝不是你想要的,并且clang会报警。