2017-03-08 105 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構造可能需要它的價值的說法, 使移動語義
  • } 地圖超出範圍
相關問題