2017-03-08 1 views
2

Je lance cet exemple très simple sur Visual Studio (2015). pour une raison quelconque, le destructeur de classe Functor est invoqué 4 fois. Je suppose que l'implémentation invoque plusieurs fois le constructeur de copie généré automatiquement, mais je suppose qu'il pourrait y avoir un bug ici. Si j'implémente un constructeur de copie moi-même, je reçois seulement 3 appels de destructeur correspondant à 1 appel de constructeur par défaut et 2 appels de constructeur de copie.std :: map avec la valeur std :: function appelle le destructeur 4 fois mais ne construit qu'un seul objet

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

sortie:

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

et si je mets en œuvre le constructeur de copie moi-même:

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

sortie:

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

quelqu'un peut-il expliquer quels objets sont détruits? Que se passe-t-il ici?

+0

sur Visual Studio aller à Debug et nous avons choisi l'étape dans (hotkey F11), et il vous montrera le programme en cours d'exécution. –

Répondre

2

Si vous implémentez votre propre constructeur de copie, le constructeur de mouvement est supprimé, donc des surcharges différentes sont sélectionnées.

Essayez ceci:

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

et ont la classe que vous êtes intéressé par Hériter de celui-ci.

Les quatre endroits dans l'original est probablement:

  • myMap[1]
    cela crée un objet par défaut construit, qui est détruit en cas de substitution. Cela crée un caractère temporaire qui est détruit à la fin de l'expression complète.
  • Functor()
  • std::function<void(void)> le constructeur de std::function prend probablement son argument valeur, pour permettre déplacer Sémantique
  • } votre carte est hors de portée