2017-03-08 108 views
2

我在Visual Studio(2015)上运行这个非常简单的例子。 由于某种原因Functor类析构函数被调用了4次。 我假设实现会调用自动生成的复制构造函数几次,但我怀疑这里可能存在一个错误。如果我自己实现一个拷贝构造函数,那么我只得到3个与1个默认构造函数调用和2个拷贝构造函数调用相对应的析构函数调用。std :: map与std :: function的值调用析构函数4次,但只构造一个对象

#include <functional> 
#include <map> 
#include <iostream> 

using namespace std; 

class Functor 
{ 
public: 

    Functor() 
    { 
     cout << "Functor::Functor()" << endl; 
    } 

    Functor& operator=(const Functor& rhs) = delete; 

    ~Functor() 
    { 
     cout << "Functor::~Functor()" << endl; 
    } 

    void operator()() 
    { 
     cout << "Functor::operator()" << endl; 
    } 

}; 

int main() 
{ 
    std::map<int, std::function<void(void)>> myMap; 

    myMap[1] = Functor(); 

    return 0; 
} 

输出:

Functor::Functor() 
Functor::~Functor() 
Functor::~Functor() 
Functor::~Functor() 
Functor::~Functor() 

,如果我实现拷贝构造自己:

Functor(const Functor& that) 
{ 
    cout << "Functor::Functor(const Functor&)" << endl; 
} 

输出:

Functor::Functor(); 
Functor::Functor(const Functor&) 
Functor::Functor(const Functor&) 
Functor::~Functor() 
Functor::~Functor() 
Functor::~Functor() 

有人可以解释哪些对象被破坏?这里发生了什么?

+0

在Visual Studio中去调试,选择了步入(热键F11),它会向您显示程序执行的一步一步。 –

回答

2

如果你实现自己的拷贝构造函数,移动构造函数是 被抑制,所以选择不同的重载。

试试这个:

struct Reporter 
{ 
    Reporter()       { cout << "Default constructor\n"; } 
    Reporter(const Reporter&)   { cout << "Copy constructor\n"; } 
    Reporter(Reporter&&)     { cout << "Move constructor\n"; } 
    Reporter& operator=(const Reporter&) { cout << "Assignment operator\n"; return *this; } 
    Reporter& operator=(Reporter&&)  { cout << "Move Assignment operator\n"; return *this; } 
    ~Reporter()       { cout << "Destructor"; } 
}; 

而且有你有兴趣继承它的类。

在原来的四个地方大概是:

  • myMap[1]
    这将创建一个默认构造的对象,重写时被破坏。
  • Functor()
    这会创建一个临时表达式,该表达式在结束时会被销毁。
  • std::function<void(void)>std::function构造可能需要它的价值的说法, 使移动语义
  • } 地图超出范围
相关问题