在 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
陈述的一个评论。你最后的输出是隐藏的,因为在最后的输出之后没有 endl
。 cout
被缓冲,这意味着它只会在下一个 endl
或缓冲区已满后写入您的控制台。所以最好写成:cout<<"something"<<endl;
到代码和初始化:
如果您在复制构造函数中获取输入对象的地址,您可以检查是否对自己进行了复制。这是一个很好的做法,因为如果您分配了无法使用默认构造函数复制的内存,则需要一个自己的复制构造函数。从我的示例中可以看出,this
和 in
的地址相同,这意味着复制构造函数想要复制到自身,如果不以特殊方式处理,这通常是错误的!
对于你的测试用例,行为只是你的对象没有被初始化,因为你将一个未初始化的对象复制到它自己,最终成为一个未初始化的对象。这绝不是您想要的,并且 clang 会报告警告。
例如,我有代码:
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 thatj
一个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
陈述的一个评论。你最后的输出是隐藏的,因为在最后的输出之后没有 endl
。 cout
被缓冲,这意味着它只会在下一个 endl
或缓冲区已满后写入您的控制台。所以最好写成:cout<<"something"<<endl;
到代码和初始化:
如果您在复制构造函数中获取输入对象的地址,您可以检查是否对自己进行了复制。这是一个很好的做法,因为如果您分配了无法使用默认构造函数复制的内存,则需要一个自己的复制构造函数。从我的示例中可以看出,this
和 in
的地址相同,这意味着复制构造函数想要复制到自身,如果不以特殊方式处理,这通常是错误的!
对于你的测试用例,行为只是你的对象没有被初始化,因为你将一个未初始化的对象复制到它自己,最终成为一个未初始化的对象。这绝不是您想要的,并且 clang 会报告警告。