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

Object that initializes to itself in C++

例如,我有代码:

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; 之外,这样的初始化是否做任何事情?

我理解如果对象被初始化为自身,则无法调用构造函数,但为什么呢?

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

您可以写:

test chk = chk;

[basic.scope.declarative]/p1

The potential scope of the first j begins immediately after that j

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

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

请记住,这不是一个好的做法,在某些情况下甚至可能导致 undefined behavior,并且 Clang 总是发出 -Wuninitialized 警告。

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

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;

到代码和初始化:

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

对于你的测试用例,行为只是你的对象没有被初始化,因为你将一个未初始化的对象复制到它自己,最终成为一个未初始化的对象。这绝不是您想要的,并且 clang 会报告警告。