3 Stimmen

C++-Konstruktor-Definition

Alle Konstruktormethoden hier tun das Gleiche. Ich benutze meistens Methode 2, habe aber heute zum ersten Mal Methode 3 gesehen. Ich habe Methode1 an einigen Stellen gesehen, weiß aber nicht, was die genauen Unterschiede zwischen ihnen sind? Welche Methode ist die beste, um Konstruktoren zu definieren und warum? Gibt es irgendwelche Probleme mit der Leistung?

  1 class Test
  2 {
  3     private:
  4         int a;
  5         char *b;
  6     public:
  7         Test(){};
  8         
  9         // method 1
 10         Test(int &vara, char *& varb) : a(vara), b(varb){}
 11         
 12         // method 2
 13         Test(int &vara, char *& varb)
 14         {
 15             a = vara;
 16             b = varb;
 17         }   
 18         
 19         //method 3
 20         Test(int &vara, char *& varb)
 21         {
 22             this->a = vara;
 23             this->b = varb;
 24         }   
 25         
 26         ~Test(){}
 27 }; 

Ich habe hier einfache Felder int und char* verwendet, was wird passieren, wenn ich viele Felder oder komplexe Typen wie struct habe?

Danke

15voto

Bei den von Ihnen verwendeten Typen wird es wahrscheinlich keinen Leistungsunterschied geben. Für Nicht-POD-Daten (Klassen mit Konstruktoren) wird jedoch das Formular:

Test(int &vara, char *& varb) : a(vara), b(varb){}

am effizientesten sein wird. Dies liegt daran, dass Nicht-POD-Daten initialisiert werden, unabhängig davon, ob Sie eine Initialisierungsliste angeben oder nicht. Die anderen Formulare, die eine Zuweisung verwenden, werden zunächst für die Initialisierung und dann für die Zuweisung verwendet.

4voto

Peter Cardona Punkte 2021

Wahrscheinlich nicht ein RIESIGER Unterschied in Bezug auf die Leistung, aber in Methode 1, Sie konstruieren a und b mit einer Kopie Konstruktor. Bei Methode 2 konstruieren Sie a und b automatisch und verwenden DANN den Zuweisungsoperator. Das könnte für komplexere Typen als int und char* langsamer sein.

Methode 3 ist genau das Gleiche wie Methode 2.

3voto

John Millikin Punkte 190278

Der erste Weg, "Initialisierungslisten" genannt, ist der beste. Sie wird für Referenzattribute benötigt und ist für Standardattribute effizienter.

Der zweite Weg ruft die Standardkonstruktoren für alle Attribute auf und verwendet dann den Zuweisungsoperator für jedes zugewiesene Attribut. Diese Methode ist langsamer und bricht möglicherweise vollständig ab, wenn ein Attributtyp keine Zuweisung unterstützt.

Die dritte Möglichkeit ist genau die gleiche wie die zweite, aber unnötig langatmig. Das Voranstellen des Attributzugriffs mit this-> ist ein schlechter Stil, es sei denn, es gibt eine lokale Variable, die ein Attribut überschattet.


Unabhängig von der Frage ist es nicht notwendig, Referenzen für Grundtypen zu verwenden. Sie fügen zusätzlichen Overhead für Zeiger Dereferenzen, und da die Werte zu Nicht-Referenzen zugewiesen werden trotzdem ist es sinnlos.

3voto

Tyler McHenry Punkte 71707

Es gibt keinen Unterschied zwischen den Methoden 2 und 3. Innerhalb einer Mitgliedsfunktion (einschließlich Konstruktoren und Destruktoren) kann eine Mitgliedsvariable x ist gleichbedeutend mit this->x . Das einzige Mal, dass dies einen Unterschied macht, ist, wenn es eine andere Variable namens x in einem näheren Rahmen. Zum Beispiel:

int Foo::memberFunc() {
  return x; // Returns member variable x. Same as return this->x.
}

int Foo::memberFunc(int x) {
  return x; // Returns the argument x. Need to say return this->x to return member x
}

Methode 1 ist in der Regel die bevorzugte Methode zur Initialisierung von Mitgliedsvariablen, da sie explizit darauf hinweist, dass Sie dies tun.

In Ihrem Fall ist es auch identisch mit den Methoden 2 und 3, aber in einigen Fällen ist es nicht so. Wenn es sich bei Ihren Mitgliedsvariablen um Konstanten, Referenzen oder Objekte ohne Standardkonstruktoren handelt, dann ist Methode1 die nur So können Sie sie initialisieren.

Ein weiterer kleiner Unterschied zu Methode 1 besteht darin, dass, wenn es sich bei Ihren Mitgliedsvariablen um Objekte handelt, diese bei Verwendung der Methoden 2 oder 3 zunächst mit ihren Standardkonstruktoren erstellt und dann geändert oder dem Konstruktorcode zugewiesen werden, während Sie sie bei Methode 1 mit einem anderen Konstruktor als dem Standardkonstruktor erstellen können.

2voto

Vijay Mathew Punkte 25917

Die erste Methode (mit Initialisierungsliste) ist die bevorzugte Methode zur Initialisierung von Mitgliedsvariablen einer C++-Klasse. Ihr Vorteil besteht darin, dass Sie wählen können, welchen Konstruktor Sie für jedes Mitglied verwenden möchten. Das Problem bei der zweiten Methode ist, dass die Standard-Konstriktoren der Mitgliedsfelder bereits aufgerufen werden, bevor der Körper des Konstruktors eingegeben wird. Dies ist auch die einzige Methode zum Aufrufen eines Basisklassenkonstruktors, wenn die Basisklasse keinen Standardkonstruktor hat. Die beiden anderen Konstruktoren sind gleich, wobei Methode 3 aus stilistischer Sicht die am wenigsten bevorzugte ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X