例如,我有代码:
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;
之外,这种初始化是否会做任何事情?
据我所知,如果对象初始化为自身,则无法调用构造函数,但为什么?
我想了解更多有关对象自身初始化的信息。
答案 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
语句的一句话。您最后一次输出是隐藏的,因为在最后一次输出后没有endl
。 cout
是缓冲的,这意味着它只会在下一个endl
或缓冲区已满后写入您的控制台。所以最好写一下:cout<<"something"<<endl;
代码和init:
如果您在复制构造函数中获取输入对象的地址,则可以检查是否对自己进行了复制。这是一种很好的做法,因为如果你已经分配了无法用默认构造函数复制的内存,你需要一个自己的复制构造函数。从我的示例中可以看出,this
和in
的地址是相同的,这意味着复制构造函数想要复制到自身,如果不以特殊方式处理,这通常是错误的!
对于您的测试用例,行为只是您的对象未初始化,因为您将未初始化的对象复制到自身,最终在未初始化的对象中。这绝不是你想要的,并且clang会报警。