2017-01-10 5 views
1

Ich habe ein Problem mit dem Klassendestruktor, der zweimal aufgerufen wird, wenn ich ein gemeinsam genutztes ptr für meine Klasse erstelle.Klassendestruktor zweimal beim Erstellen eines shared_ptr aufgerufen

Ich versuche, einen Vektor von Objekten zu erstellen, und jedes Objekt hat einen Konstruktor und einen Destruktor.

Wenn ich einen Anruf machen, wie:

std::vector<std::shared_ptr<ServoController>> servos; 
bool CreateServo(int id) 
{ 
    std::shared_ptr<ServoController> servo = std::make_shared<ServoController>(ServoController(id)); 
    servos.push_back(servo); 
} 

Der Konstruktor für Servo-Controller genannt wird und dann sofort der Destructor für Servo-Controller genannt wird, bevor es die push_back Funktion aufgerufen wird sogar.

Dann, wenn ich meine Anwendung schließe, wird der Destruktor für ServoController erneut aufgerufen. Aber der Konstruktor wurde bisher nur einmal genannt (ich habe nur 1 Objekt im Vektor). Sollte es nicht wenigstens den Konstruktor wieder laufen lassen?

Gibt es eine Möglichkeit, einen Vektor meiner Klasse zu erstellen, und für jedes Objekt im Vektor sollte der Konstruktor einmal aufgerufen werden, und der Destruktor sollte einmal aufgerufen werden, wenn die Objekte aus dem Vektor oder dem Vektor entfernt werden ist zerstört?

Danke, -D

Antwort

11

Sie mit diesem Aufruf ein temporäres Objekt zu schaffen, das ist das, was den ersten (unerwarteten) Destruktoraufrufs verursacht ist.

std::make_shared<ServoController>(ServoController(id)); 

Die Abfolge der Ereignisse ist:

  • ServoController(id) erstellt ein neues temporäres Objekt, das als Argument an std::make_shared geben wird.
  • std::make_shared<ServoController> dann leitet das temporäre Objekt an ServoController 's kopieren Konstruktor (was wahrscheinlich nicht das ist, was Sie wollen). Aus diesem Grund wird Ihr Hauptkonstruktor nur einmal aufgerufen.
  • Dies erstellt ein neues Objekt auf dem Heap (verwaltet von der shared_ptr), die eine Kopie der temporären Sie erstellt wurde.
  • Das temporäre Objekt wird dann sofort zerstört, was den Destruktor das erste Mal aufruft.

Was Sie wirklich wollen, ist:

std::make_shared<ServoController>(id); 

std::make_shared leitet seine Argumente direkt an den Konstruktor für die Template-Argument. Sie brauchen den zusätzlichen Konstruktoraufruf nicht dort.

+0

Es könnte ein Move-Konstruktor sein, der aufgerufen wurde, im Gegensatz zu einem Kopierkonstruktor. –

Verwandte Themen