为什么在删除对象之前调用复制构造函数?

cfi*_*her 1 c++ constructor destructor memory-management copy-constructor

我有以下类,其中包括一个复制构造函数:

头文件:Fred.h

namespace foo {


class Fred {
private:
    int _x;
    int _y;


public:
    Fred();                         // Default constructor
    Fred(Fred const &other);        // Copy constructor
    Fred(int x, int y);             // Regular parameters
    ~Fred();                        // Destrcutor

};


}
Run Code Online (Sandbox Code Playgroud)

实现文件:Fred.cpp

#include "Fred.h"
#include <iostream>

foo::Fred::Fred(){
    _x = 0;
    _y = 0;

    std::cout << "Calling the default constructor\n";
}

foo::Fred::Fred(Fred const &other){

    _x = other._x;
    _y = other._y;

    std::cout << "Calling the copy constructor";
}

foo::Fred::Fred(int x, int y){
    _x = x;
    _y = y;

    std::cout << "Calling the convenience constructor\n";
}

foo::Fred::~Fred(){

    std::cout << "Goodbye, cruel world!\n";
}
Run Code Online (Sandbox Code Playgroud)

我希望看到析构函数在超出范围时调用,而是调用复制构造函数然后调用析构函数.为什么要创建副本?我是否泄漏记忆?

using namespace foo;

int main(int argc, const char * argv[])
{



    {
        Fred f2 = *new Fred();

    } // I was expecting to see a destructor call only


    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*our 5

那是因为你正在使用内存泄漏操作符 *new.

分配的对象new永远不会自动删除; 只有明确使用delete.您的代码动态分配对象,将其复制到f2,然后丢失唯一指向动态对象的指针.

如果您只是想创建一个本地对象:

Fred f2;
Run Code Online (Sandbox Code Playgroud)

当您确实需要动态分配时(换句话说,如果对象需要比当前范围更长),请始终使用RAII对象(如智能指针)来避免内存泄漏.例如:

std::unique_ptr<Fred> f2(new Fred);   // C++11 - no "delete" needed
auto f2 = std::make_unique<Fred>();   // C++14 - no "new" or "delete" needed
Run Code Online (Sandbox Code Playgroud)