2017-03-08 2 views
2

Visual Studio(2015)でこの非常に簡単な例を実行します。 何らかの理由でFunctorクラスのデストラクタが4回呼び出されます。 実装が自動生成されたコピーコンストラクタを数回呼び出すと仮定しますが、ここにバグがある可能性があります。コピーコンストラクタを自分で実装すると、1つのデフォルトのコンストラクタ呼び出しと2つのコピーコンストラクタ呼び出しに対応するデストラクタ呼び出しが3つだけになります。std :: mapはstd :: functionの値を使用してdestructorを4回呼び出しますが、1つのオブジェクトのみを構築します

#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

を行く移動-セマンティクスを有効にするために、それは値によって引数の を取るデバッグに移動し、(ホットキーにステップを選択しました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"; } 
}; 

をそして、あなたはそれから継承に興味のあるクラスを持っています。

元の4つの場所は、おそらくです:

  • myMap[1]
    これはオーバーライドされると、破壊されますデフォルトで構築オブジェクトを作成します。
  • Functor()
    これは、完全な式の最後に破棄される一時的なものを作成します。
  • std::function<void(void)> std::functionのコンストラクタは、おそらく
  • } マップは、Visual Studioにはスコープの外に
関連する問題