问题描述
通过查看示例:
#include <iostream>
int wow=0;
class Foo{
int cow = 0;
public:
Foo(){
std::cout << "Foo +\n";
cow = 0;
++wow;
}
Foo(int n){
std::cout << "Foo has " << n << "\n";
cow = n;
++wow;
}
~Foo(){
std::cout << cow << " ~ Foo -\n";
}
void print(){
std::cout << cow << " is the foo#\n";
}
};
int main(){
void * bar = ::operator new(sizeof(Foo));
Foo * a = new(bar) Foo;
*a = Foo(10);
std::cout << wow << std::endl;
a->~Foo();
::operator delete(bar);
return 0;
}
并编译运行,控制台显示:
Foo+
Foo has 10
10 ~ Foo -
2
10 ~ Foo -
第一个析构函数调用应该是 0 ~ Foo -
吗?因为那是第一个 Foo
被Foo(10)
覆盖?
解决方法
在这个赋值语句中
*a = Foo(10);
创建了一个 Foo
类型的临时对象,该对象使用默认的复制赋值运算符(此处不调用复制或移动构造函数)分配给表达式 *a
指定的对象。分配后临时对象被删除。指针 cow
指向的对象的未声明变量 Foo
(它似乎是类 a
的数据成员)现在包含相同的值 10
。并且在程序的最后,指针a
指向的对象也被删除了。
结果你会收到两条消息
10 ~ Foo -
10 ~ Foo -
第一个由临时对象的析构函数生成,第二个由指针a
指向的对象生成。