CPP2019SSF21

Aus Verteilte Systeme - Wiki
Zur Navigation springen Zur Suche springen

Feature: Delegating Constructors

  • Eingeführt in: C++11

Use Cases

Erlaubt es (Delegating-)Konstruktoren sogenannte Target-Konstruktoren aufzurufen, und so gemeinsame Initialisierungen im Target-Konstruktor zusammenzufassen.
Target-Konstruktoren können dabei selbst auch Delegating-Konstruktoren sein.

Syntax

class A{
public:
   A() : A(42) { }
   A(int i) : A(i, 17) { }
   A(int i, int j) {   
      a=i;
      b=j;
      avg=(a+b)/2;
  }
private:
   int a;
   int b;
   int avg;
};
Syntax Delegating-Konstruktor Aufgerufener Target-Konstruktor
A() : A(42) { } A() A(int i)
mit i=42
A(int i) : A(i, 17) { } A(int i) A(int i, int j)
mit i=i und j=17

Motivation für die Einführung

Vor der Einführung der Delegating Constructors gab es keine elegante Möglichkeit, gemeinsame Initialisierungen unterschiedlicher Konstruktoren an einem Ort zu verwalten.

Vorherige Lösungsansätze

1. Initialisierung in jedem Konstruktor duplizieren

  • Aufwändig zu supporten und unschön
class A{
public:
   A():             a(0), b(0) {avg = (a+b)/2;}
   A(int i):        a(i), b(0) {avg = (a+b)/2;}
   A(int i, int j): a(i), b(j) {avg = (a+b)/2;}
private:
   int a;
   int b;
   int avg;
};

2. Initialisierung in Member Function

  • Andere Member Functions könnten versehentlich initialisierende Member Function aufrufen.
  • Class Members sind bereits "konstruiert", wenn initialisierende Member Function aufgerufen wird.
class A{
public:
   A():             a(0), b(0) {init();}
   A(int i):        a(i), b(0) {init();}
   A(int i, int j): a(i), b(j) {init();}
private:
   int a;
   int b;
   int avg;
   void init() {avg = (a+b)/2;};
};

Warnhinweise

Delegating-Konstruktoren dürfen sich nicht direkt oder indirekt selbst als Target-Konstruktor aufrufen -> Endlosschleife. (ill-formed behaviour)

Delegating-Konstruktoren dürfen keine Class Member in ihrer Initializer-List initialisieren. -> (Member Initializer List ODER Delegating)

Delegating-Konstruktoren warten zunächst auf die Ausführung der delegierten Konstruktoren, bevor sie ihren eigenen Code ausführen.

class A{
public:    
   A(): A(0){ cout << "In A()" << endl;}
   A(int i): A(i, 0){cout << "In A(int i)" << endl;}
   A(int i, int j){
      a=i;
      b=j;
      avg=(a+b)/2;
      cout << "In A(int i, int j)" << endl;}  
private:
   int a;
   int b;
   int avg;
};

int main(){
   class A a;
   return 0;
}

Die Ausgabe dieses Beispiels wäre:

In A(int i, int j)
In A(int i)
In A()

Präsentation

PDF

Quellen

IBM Community Blogs IBM Knowledge Center CppReference