简体   繁体   English

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

[英]C++ basic constructors/vectors problem (1 constructor, 2 destructors)

Question is probably pretty basic, but can't find out what's wrong (and it leads to huge of memleaks in my app): 问题可能很基本,但是无法找出问题所在(这会导致我的应用中出现大量的内存泄漏):

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";
}

The output is: 输出为:

1
2
constructor();
3
4
destructor();
destructor();
  1. Why are there 2 destructors? 为什么会有2个析构函数?
  2. If it's because a copy is created to be inserted into vector - how come "operator=" is never called? 如果是因为创建了一个副本以将其插入到vector中,那么为什么永远不会调用“ operator =“?

When the b object gets pushed onto the vector a copy is made, but not by the operator=() you have - the compiler generated copy constructor is used. 当b对象被推到向量上时,将创建一个副本,但不是由您拥有的operator=()生成的-使用编译器生成的副本构造函数。

When the main() goes out of scope, the b object is destroyed and the copy in the vector is destroyed. 当main()超出范围时, b对象将被销毁,向量中的副本也将被销毁。

Add an explicit copy constructor to see this: 添加一个显式副本构造函数以查看此内容:

MyClass( MyClass const& other) {
    cout << "copy ctor\n";
};

If you want to log all copies and constructions you should add an explicit copy constructor so that the compiler doesn't create one for you. 如果要记录所有副本和构造,则应添加一个显式副本构造函数,以便编译器不会为您创建一个副本构造函数。

MyClass( const MyClass& )
{
    cout << "Copy constructor\n";
}

You can, in your copy constructor, call your assignment operator. 您可以在副本构造函数中调用您的赋值运算符。 It is a reasonably common way of implementing things, however with your definition of operator=, this may have serious problems. 这是一种合理的通用实现方式,但是根据您对operator =的定义,这可能会带来严重的问题。

You have an unconventional implementation of operator=. 您具有operator =的非常规实现。 operator= should return a reference to the class on which it is called (to enable proper chaining), but you return a new class instance by value. operator =应该返回对其调用的类的引用 (以启用正确的链接),但是您需要按值返回新的类实例。 This means that if you tried to call operator= from your copy constructor you may well end up with infinite recursion. 这意味着,如果您尝试从副本构造函数中调用operator =,则可能会导致无限递归。 Try this operator= instead: 尝试使用此operator =代替:

MyClass& operator=( const MyClass& )
{
    cout << "operator=\n";
    return *this;
}

When defining an assignment operator you should always consider the possibility that the parameter and *this may refer to the same object and ensure that the definition of the operator won't have any unintended effects in this scenario. 在定义赋值运算符时,应始终考虑参数和* this可能指向同一对象的可能性,并确保在这种情况下,运算符的定义不会产生任何意外的影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM