C ++基本构造函数/向量问题(1个构造函数,2个析构函数)

时间:2009-06-14 08:25:59

标签: c++

问题可能是非常基本的,但无法找出问题所在(这会导致我的应用程序中出现大量的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();
  1. 为什么有2个析构函数?
  2. 如果是因为创建了一个副本以插入向量 - 为什么“operator =”从未被调用?

2 个答案:

答案 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可能引用同一对象的可能性,并确保运算符的定义在此方案中不会产生任何意外影响。