2016-09-10 1 views
1

Gibt es einen Unterschied zwischen Demo1 und Demo2 im folgenden Code?Gibt es einen Unterschied zwischen "my_constructor: variable (x)" und "this.variable = x" im Konstruktor?

#include <iostream> 

class Base {}; 

class Demo1 : public Base { 
public: 
    Demo1() : instance_variable(5) { 

    } 

    int instance_variable; 
}; 

class Demo2 : public Base { 
public: 
    Demo2() { 
     this->instance_variable = 5; 
    } 

    int instance_variable; 
}; 

int main(int argc, char **argv) 
{  
    Demo1 a;  
    Demo2 b; 

    std::cout << "a.instance_variable: " << a.instance_variable << std::endl; 
    std::cout << "b.instance_variable: " << b.instance_variable << std::endl; 

    return 0; 
} 

sah ich die erste Schreibweise in einem Buch, das ich gerade lese, und ich bin nicht sicher, ob die beiden gleich sind oder wenn Demo1 feine Unterschiede hat, sollte ich bewusst sein.

Ich finde die zweite viel lesbarer, da ich von einem Java/JavaScript-Hintergrund komme, also bin ich gespannt, ob ich "Demo1" durch "Demo2" ersetzen kann, ohne die Bedeutung des Codes zu ändern.

Auch, was ist der Ausdruck "Konstruktor: field (x) {}" genannt?

+0

Ich schlage vor, Sie lesen Sie diese: http://stackoverflow.com/questions/6822422/c-where-to-initialize-variables-in-constructor – Meraj99

+1

Initialisiererliste –

+0

@SauravSahu Dank, dass es! Aber ist es gleichwertig? Sende die Antwort, damit ich sie annehmen kann. – Dmitry

Antwort

1

Wenn Sie eine Programmierung Hintergrund haben (wie Sie gesagt haben, Sie haben), dann sollten Sie auch der Unterschied zu einem gewissen Variable zwischen initializing Wert der Variablen und assignment eines Wertes bewusst sein.

Demo1 wird die Variable Initialisierung mit (instance_variable wird initialisiert im Mitglied Initialisiererliste, Demo() : instance_variable(5)), aber Demo2 ist Wert auf die instance_variable

Zuweisung Ich bin nicht sicher, ob die zwei sind gleichwertig oder wenn Demo1 feine Unterschiede hat, die ich beachten sollte.

Nein. Die beiden sind nicht gleichwertig.

  • Demo1 ist die instance_variable initialisiert, bedeutet Copykonstruktor wird (im Fall, wenn instance_variable ist Objekt) aufgerufen werden.
  • Aber die Demo2 zuweist Wert auf die Variable, nachdem sie initialisiert wurde (Default-Konstruktor aufgerufen wurde, und jetzt wird operator= kopieren Werte genannt werden)

Auch, was der Ausdruck constructor:field(x){} genannt ?

Es heißt member initializer list.

EDIT

Mitglied Initialisiererliste macht nur einen Unterschied, wenn Objekte zu initialisieren, aber im Fall von Primitiven, in beiden Richtungen (Demo1 und Demo2), sie sind so ziemlich das gleiche.

Und es ist eine andere Sache, die Sie wissen sollten, ist, dass Sie Mitglied Initialisiererliste verwenden müssen werden initialisieren:

  • konst Datenelemente
  • Mitglied Referenz Variablen
  • Initialisierung dieser Membervariablen (Objekte einer Klasse), die keinen Standardkonstruktor haben.
  • und beim Übergeben von Parametern an den Basisklassenkonstruktor.
+0

Also kommt der Hauptunterschied zwischen ihnen zum Tragen, wenn die Instanzvariable ein Objekt und nicht ein Primitiv ist? Sind sie im Falle von Primitiven gleichwertig (es gibt keine Zerstörung, sie geht einfach außer Reichweite)? – Dmitry

+1

Der zusätzliche Overhead wird bei Objekten ja sein. Aber im Falle von Primitiven sind sie ziemlich gleich. –

6

Es kann einen Unterschied geben. Als Ergebnis wird der erste Ansatz, Konstruktorinitialisierer Syntax, als besser angesehen.

In Demo2 wird alles default-initialisiert und dann wird der Operator = verwendet, um den neuen Wert zu geben. Da dein instance_variable nur ein int ist, ist das egal. Aber es wird wichtig, wenn:

  • der Standard-Konstruktor, Operator = oder beides sind rechnerisch teuer
  • gibt es keine Standard-Konstruktor
  • die Variable const oder eine Referenz, dh Sie können nicht Operator = um den Wert zu ändern
  • Die Variable ist eine Instanz einer Klasse, die counter-intuitiv geschrieben wurde, so dass Sie tatsächlich andere Ergebnisse von einem Konstruktor erhalten, der ein Argument als von einem Standardkonstruktor gefolgt von Zuweisung nimmt. Obwohl solche Klassen nicht existieren sollten, bedeutet das nicht, dass sie nicht existieren.

Da der Demo1 Weg ist manchmal schneller (nie langsamer) und arbeitet in Fällen, in denen die Demo2 Weg nicht der Fall ist, ist es die Technik bevorzugt ist. Es mag zwar ungewöhnlich für diejenigen sein, die aus anderen Sprachen kommen, aber so sollten Sie Ihre Konstruktoren schreiben.

0

Demo1 verwendet member initializer list. Es ruft den Konstruktor instance_variable mit dem Argument 5 auf.

Demo2 verwendet das copy assignment operator von instance_variable mit dem Argument 5. In Ihrem Fall, da instance_variable ein int ist, gibt es keinen Unterschied. Wenn jedoch instance_variable ein Objekt einer Klasse ist, die sich bei der Initialisierung und der Kopierzuordnung anders verhält, würde es einen Unterschied geben.

0
  1. dies wird als „Mitglied der Initialisierung“ genannt
  2. für und int es macht keinen Unterschied. Bei komplexen Objekten ruft das Member-Init den c-tor des Members einmal mit den benötigten Parametern auf, anstatt den Standard-Cotr aufzurufen und dann die Eigenschaften manuell einzurichten.
0

Verwenden Mitglied Initialisiererliste (Demo 1):

A.) Copykonstruktor der Variablen wird als instance_variable(value) genannt. B.) Destructor wird aufgerufen, wenn value den Gültigkeitsbereich verlässt.

copy constructor + destructor call 

Initialisierung innerhalb Konstruktor Block (Demo 2): A.) Copykonstruktor der Variablen wird als instance_variable(value) genannt. B.) Zuweisungsoperatoraufruf innerhalb des Konstruktorkörpers. C.) Destructor wird aufgerufen, wenn value den Gültigkeitsbereich verlässt. Diese

constructor + one addition assignment operator call(for complex and Non-PODs) + destructor 

ZuordnungStrafe wird viel mehr in „echten“ Anwendungen, bei denen es viele solche komplexe Objekte zu initialisieren. Sie tun int Zuweisung, also kein Unterschied IMO.

Read more.

Verwandte Themen