问题可能是非常基本的,但无法找出问题所在(这会导致我的应用程序中出现大量的memleaks):
class MyClass {
public:
MyClass() { cout << "constructor();\n"; };
MyClass operator= (const MyClass& b){
cout << "operator=;\n"; return MyClass();
};
~MyClass() { cout << "destructor();\n"; };
};
main() {
cout << "1\n";
vector<MyClass> a;
cout << "2\n";
MyClass b;
cout << "3\n";
a.push_back(b);
cout << "4\n";
}
输出结果为:
1
2
constructor();
3
4
destructor();
destructor();
答案 0 :(得分:4)
当b对象被推送到向量上时,会产生一个副本,而不是你所拥有的operator=()
- 使用编译器生成的复制构造函数。
当main()超出范围时,b
对象将被销毁,向量中的副本将被销毁。
添加一个显式的复制构造函数来查看:
MyClass( MyClass const& other) {
cout << "copy ctor\n";
};
答案 1 :(得分:3)
如果要记录所有副本和构造,则应添加显式复制构造函数,以便编译器不会为您创建一个。
MyClass( const MyClass& )
{
cout << "Copy constructor\n";
}
您可以在复制构造函数中调用赋值运算符。这是一种相当常见的实现方式,但是对于operator =的定义,这可能会有严重的问题。
你有一个非常规的operator =实现。 operator =应该将引用返回到调用它的类(以启用正确的链接),但是按值返回一个新的类实例。这意味着如果你试图从你的拷贝构造函数中调用operator =,你最终可能会得到无限递归。试试这个operator =而不是:
MyClass& operator=( const MyClass& )
{
cout << "operator=\n";
return *this;
}
定义赋值运算符时,应始终考虑参数和* this可能引用同一对象的可能性,并确保运算符的定义在此方案中不会产生任何意外影响。