Intern und in Bezug auf den generierten Code gibt es einen wirklichen Unterschied zwischen:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
und
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
Vielen Dank...
Intern und in Bezug auf den generierten Code gibt es einen wirklichen Unterschied zwischen:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
und
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
Vielen Dank...
Angenommen, diese Werte sind primitive Typen, dann gibt es keinen Unterschied. Initialisierungslisten machen nur dann einen Unterschied, wenn Sie Objekte als Mitglieder haben, da Sie anstelle der Standardinitialisierung mit anschließender Zuweisung in der Initialisierungsliste das Objekt auf seinen endgültigen Wert initialisieren können. Dies kann tatsächlich spürbar schneller sein.
Sie müssen die Initialisierungsliste verwenden, um konstante Mitglieder, Referenzen und Basisklassen zu initialisieren
Wenn Sie konstante Elemente, Referenzen und Parameter an Basisklassenkonstruktoren initialisieren müssen, wie in den Kommentaren erwähnt, müssen Sie die Initialisierungsliste verwenden.
Beispiel (nicht erschöpfend) Klasse / Struktur enthält Referenz:
Ein Beispiel für die Initialisierung einer Basisklasse, für die ein Parameter erforderlich ist (z. B. kein Standardkonstruktor):
quelle
_capacity
,_data
und_len
haben Klassentypen ohne zugängliche Standardkonstruktoren?const
im Konstruktorkörper nicht initialisieren können. Sie müssen die Initialisierungsliste verwenden. Nicht-const
Mitglieder können in der Initialisierungsliste oder im Konstruktorkörper initialisiert werden.Ja. Im ersten Fall können Sie erklären
_capacity
,_data
und_len
als Konstanten:Dies ist wichtig, wenn Sie die
const
Aktualität dieser Instanzvariablen sicherstellen möchten, während Sie ihre Werte zur Laufzeit berechnen. Beispiel:const
Instanzen müssen in der Initialisierungsliste initialisiert werden, oder die zugrunde liegenden Typen müssen öffentliche parameterlose Konstruktoren bereitstellen (was primitive Typen tun).quelle
Ich denke, dieser Link http://www.cplusplus.com/forum/articles/17820/ bietet eine hervorragende Erklärung - insbesondere für diejenigen, die neu in C ++ sind.
Der Grund, warum Intialiser-Listen effizienter sind, besteht darin, dass innerhalb des Konstruktorkörpers nur Zuweisungen stattfinden, keine Initialisierung. Wenn Sie also mit einem nicht integrierten Typ arbeiten, wurde der Standardkonstruktor für dieses Objekt bereits aufgerufen, bevor der Hauptteil des Konstruktors eingegeben wurde. Innerhalb des Konstruktorkörpers weisen Sie diesem Objekt einen Wert zu.
Tatsächlich ist dies ein Aufruf des Standardkonstruktors, gefolgt von einem Aufruf des Kopierzuweisungsoperators. Mit der Initialisiererliste können Sie den Kopierkonstruktor direkt aufrufen. Dies kann manchmal erheblich schneller sein (denken Sie daran, dass sich die Initialisiererliste vor dem Hauptteil des Konstruktors befindet).
quelle
Ich füge hinzu, dass die Initialisierung die einzige Möglichkeit ist, Ihre Klasse zu erstellen, wenn Sie Mitglieder vom Klassentyp haben, für die kein Standardkonstruktor verfügbar ist.
quelle
Ein großer Unterschied besteht darin, dass die Zuweisung Mitglieder einer übergeordneten Klasse initialisieren kann. Der Initialisierer funktioniert nur mit Mitgliedern, die im aktuellen Klassenbereich deklariert sind.
quelle
Hängt von den beteiligten Typen ab. Der Unterschied ist ähnlich zwischen
und
Wenn die zweite Form die Initialisierungsliste ist, macht es einen Unterschied, ob der Typ Konstruktorargumente erfordert oder mit Konstruktorargumenten effizienter ist.
quelle
Der wahre Unterschied besteht darin, wie der gcc-Compiler Maschinencode generiert und den Speicher festlegt. Erklären:
Es gibt sicherlich andere Möglichkeiten, mit Mitgliedern vom Typ const umzugehen. Um ihnen das Leben zu erleichtern, beschließen die Autoren des gcc-Compilers, einige Regeln aufzustellen
quelle
Es gibt nur eine Möglichkeit, Basisklasseninstanzen und nicht statische Elementvariablen zu initialisieren , nämlich die Initialisierungsliste.
Wenn Sie in der Initialisierungsliste Ihres Konstruktors keine Basis- oder nicht statische Elementvariable angeben, wird dieses Element oder diese Basis entweder standardmäßig initialisiert (wenn das Element / die Basis ein Nicht-POD-Klassentyp oder ein Array einer Nicht-POD-Klasse ist Typen) oder anderweitig nicht initialisiert.
Sobald der Konstruktorkörper eingegeben wurde, wurden alle Basen oder Mitglieder initialisiert oder nicht initialisiert (dh sie haben einen unbestimmten Wert). Im Konstruktorkörper gibt es keine Möglichkeit zu beeinflussen, wie sie initialisiert werden sollen.
Möglicherweise können Sie Mitgliedern im Konstruktorkörper neue Werte zuweisen, aber es ist nicht möglich,
const
Mitgliedern oder Mitgliedern des Klassentyps zuzuweisen, die nicht zuweisbar gemacht wurden, und es ist nicht möglich, Referenzen erneut zu binden.Bei integrierten Typen und einigen benutzerdefinierten Typen kann die Zuweisung im Konstruktorkörper genau den gleichen Effekt haben wie die Initialisierung mit demselben Wert in der Initialisierungsliste.
Wenn Sie ein Mitglied oder eine Basis in einer Initialisierungsliste nicht benennen und diese Entität eine Referenz ist, einen Klassentyp ohne vom Benutzer deklarierten Standardkonstruktor hat,
const
qualifiziert ist und einen POD-Typ hat oder ein POD-Klassentyp oder ein Array vom POD-Klassentyp ist Wenn Sie einconst
qualifiziertes Mitglied (direkt oder indirekt) enthalten, ist das Programm schlecht ausgebildet.quelle
Wenn Sie eine Initialisierungsliste schreiben, erledigen Sie alles in einem Schritt. Wenn Sie keine Initilizer-Liste schreiben, führen Sie zwei Schritte aus: einen für die Deklaration und einen für die Zuweisung des Werts.
quelle
Es gibt einen Unterschied zwischen der Initialisierungsliste und der Initialisierungsanweisung in einem Konstruktor. Betrachten wir den folgenden Code:
Wenn MyClass verwendet wird, werden alle Mitglieder vor der ersten Anweisung in einem ausgeführten Konstruktor initialisiert.
Wenn MyClass2 verwendet wird, werden jedoch nicht alle Mitglieder initialisiert, wenn die erste Anweisung in einem Konstruktor ausgeführt wird.
In einem späteren Fall kann es zu einem Regressionsproblem kommen, wenn jemand einem Konstruktor Code hinzufügt, bevor ein bestimmtes Mitglied initialisiert wird.
quelle
Hier ist ein Punkt, den andere nicht erwähnt haben:
Die temporäre Klasse hat keinen Standard-Ctor. Wenn wir es in einer anderen Klasse wie folgt verwenden:
Der Code wird nicht kompiliert, da der Compiler nicht weiß, wie er initialisiert werden soll
obj
, weil er nur einen expliziten ctor hat, der einen int-Wert empfängt. Daher müssen wir den ctor wie folgt ändern:Es geht also nicht nur um const und Referenzen!
quelle