Können Sie den Klassenkonstruktor eines instanziierten Objekts explizit in C ++ aufrufen?

8

Können wir nach dem Erstellen einer Instanz einer Klasse den Konstruktor explizit aufrufen? Zum Beispiel

%Vor%

Können wir das tun?

    
Lakshmi 24.11.2008, 11:01
quelle

7 Antworten

14

Sie können das Placement neu verwenden: Ссылка , das erlaubt

%Vor%

In Ihrem Beispiel würden Sie jedoch zweimal einen Konstruktor für ein Objekt aufrufen, was sehr schlecht ist. Stattdessen würde ich Ihnen empfehlen, einfach

zu tun %Vor%

Neu platzieren wird normalerweise nur verwendet, wenn Sie den Speicher z. in einem benutzerdefinierten Speichermanager.

    
Michael Platings 24.11.2008, 11:04
quelle
10

Nein.

Erstellen Sie eine Methode für die Menge und rufen Sie sie über den Konstruktor auf. Diese Methode steht dann auch für später zur Verfügung.

%Vor%

Wahrscheinlich möchten Sie auch einen Standardwert oder einen Standardkonstruktor.

    
brofield 24.11.2008 11:18
quelle
4

Nein

%Vor%

Wenn eine Funktion / Funktionalität im Konstruktor benötigt wird oder nachdem ein Objekt konstruiert wurde, wird es normalerweise in die init () -Methode gestellt und auch im Konstruktor und an anderer Stelle verwendet.

Beispiel:

%Vor%     
yesraaj 24.11.2008 11:51
quelle
2

Ich bin mir ziemlich sicher, dass Sie das nicht tun können. Das ist der springende Punkt, Konstruktor IS erstellt eine Instanz der Klasse.

Wenn ein Konstruktor überhaupt nicht aufgerufen wird oder zweimal aufgerufen wird - welche Konsequenzen könnte er haben?

Was Sie natürlich tun könnten, ist das Extrahieren einer Konstruktorlogik in die Methode und das Aufrufen dieser Methode sowohl im Konstruktor als auch nach der Erzeugung des Objekts.

    
badbadboy 24.11.2008 11:08
quelle
1

Das klingt übrigens nach einem Konstruktionsfehler. Sobald ein Objekt konstruiert ist, sollte es niemals notwendig sein, es neu zu konstruieren. Eine solche Wiederverwendung von Variablennamen macht den Code eher schwierig zu verstehen. Aus diesem Grund ist es oft falsch (aber manchmal unvermeidbar), herstellerspezifische Funktionen über eine zusätzliche Funktion init oder set verfügbar zu machen.

Wie Michael bereits gesagt hat, könnte die Platzierung neu hier verwendet werden, ist aber wirklich für verschiedene Zwecke gedacht. Bevor Sie ein neues Objekt an einem Speicherort erstellen, müssen Sie das alte Objekt explizit löschen:

%Vor%

Außerdem kann placement new einen negativen Effekt auf Ihren Speicher haben, da Überladungen erwarten könnten, dass der Speicher, der übergeben wird, zum Heap gehört! Fazit: nicht . machen. das.

BEARBEITEN Um zu zeigen, dass der Aufruf des Destruktors ist wirklich notwendig (für Nicht-POD), betrachten Sie den folgenden Beispielcode:

%Vor%

Wie erwartet, liefert das Programm folgende Ausgabe:

%Vor%

... was bedeutet, dass der Destruktor für das erste Objekt nicht aufgerufen wird. Das gleiche gilt für alle Ressourcen, die A möglicherweise erworben hat.

    
Konrad Rudolph 24.11.2008 18:50
quelle
0

Nein, das kannst du nicht tun. Die einzige Möglichkeit, einen Konstruktor aufzurufen, ist das Schlüsselwort "new".

    
Shadow 18.03.2009 05:38
quelle
-1

Zusammenfassend lässt sich sagen, dass die drei Möglichkeiten, den expliziten Konstruktor anzugeben, über

erfolgen
  1. Eine Instanz (2); // tut A instance = 2; jemals arbeiten?

  2. A * Instanz = neu A (2); // nie sicher über & amp; versus * hier, ich

  3. new (& amp; instance) A (2);

und Aromen von denen. Das Ziel idee besteht darin, dafür zu sorgen, dass zu keiner Zeit ein Objekt konstruiert wird, das sich nicht in einem richtigen initialisierten Zustand befindet, und Konstrukteure sollen dies sicherstellen. (Dies bedeutet, dass Methoden nicht prüfen müssen, ob eine .init (...) Methode erfolgreich aufgerufen wurde oder nicht.)

Dies scheint mir der funktionellste Weg zu sein, insbesondere für Klassen, die Teile von Frameworks sind und in Bibliotheken wiederverwendet werden. Wenn Sie daran interessiert sind, arbeiten Sie daran, dass alle Konstruktoren, einschließlich der Standardkonstruktoren, eine voll funktionsfähige Instanz bereitstellen.

Ausnahmefälle: Es gibt Dinge, die Sie in der Konstruktoroperation möglicherweise nicht haben, wenn es möglich ist, dass sie fehlschlagen, es sei denn, es ist angemessen, eine Ausnahme vom Konstruktor zu werfen. Und manche Leute haben gerne "leere" Instanzen, die mit nachfolgenden Methoden propagiert werden und sogar Initialisierungs-Mitglieder. Es ist interessant, Möglichkeiten zu finden, um solche Situationen zu mildern, und robuste Instanzen zu haben, die keine schlechten Zustände haben, gegen die in Methodenimplementierungen und bei der Verwendung geschützt werden muss.

PS: In einigen komplexen Fällen kann es nützlich sein, eine initialisierte Instanz (Referenz) als Ergebnis einer Funktion oder einer Methode in einer "Factory" -Klasse zu liefern, so dass die Zwischen-, Unter-Setup-Instanz wird nie außerhalb der Kapselungsklasse oder -funktion der Factory-Klasse gesehen. Das gibt uns,

+4. Eine * Instanz = MakeAnA (2);

+5. Eine * Instanz = InterestingClass.A (2);

    
orcmid 24.11.2008 18:27
quelle

Tags und Links