Diskussion:C++-Programmierung/ Eigene Datentypen definieren

Aus Wikibooks
Zur Navigation springen Zur Suche springen

Frage zum Thema expliziter Konstruktoraufruf[Bearbeiten]

Wenn ich einen Konstruktor mir zwei Parametern habe, dann läßt der sich implizit durch (param1,param2) aufrufen. Definiere ich einen anderen Konstruktor "explicit", so geht das mit dem ersten nicht mehr, explizit läßt aber auch der sich immer noch aufrufen.

Wo ist das Problem? --134.102.29.134 19:27, 30. Jan. 2013‎ (CET) Unterschrift nachgetragen --Prog 05:33, 31. Jan. 2013 (CET)[Beantworten]

Ok, hat sich geklärt:

(param1, param2) ist keine Initialisierungsliste, sondern wird zunächst ausgewertet (Klammer-Operator, dann Komma-Operator). Letzterer gibt definitionsgemäß param2 zurück. Zufällig ließ dieser sich implizit in einen anderen Konstruktor konvertieren, dies war aber "unglücklicherweise" genau derjenige, den ich im zweiten Schritt auf explizit gesetzt hatte, Folge Kompilerfehler! --134.102.29.134 19:38, 30. Jan. 2013‎ (CET) Unterschrift nachgetragen --Prog 05:33, 31. Jan. 2013 (CET)[Beantworten]

Explizite Konstruktoren wirken sich nur bei einem Parameter aus. Sobald der Konstruktor mehr als einen Parameter besitzt, kann über ihn keine implizite Umwandlung vorgenommen werden, er ist somit immer "explizit".
Ich vermute du hast so was in der Art gemacht:
Nuvola-inspired-terminal.svg
#include <iostream>

struct A{
    A(int a):v1(a){}
    A(double a, int b):v1(b),v2(a){}

    int v1;
    double v2;
};

int main(){
    A o = (3.14159, 7); // ganz böse falsch!
    std::cout << o.v1 << ", " << o.v2 << std::endl;
}
Crystal Clear app kscreensaver.svg
Ausgabe:
7, 2.07339e-317
Wie die Ausgabe zeigt ist das ein impliziter Aufruf des Konstruktors mit einem Parameter. Richtig wäre:
Nuvola-inspired-terminal.svg
#include <iostream>

struct A{
    A(int a):v1(a){}
    A(double a, int b):v1(b),v2(a){}

    int v1;
    double v2;
};

int main(){
    A o(3.14159, 7);
    std::cout << o.v1 << ", " << o.v2 << std::endl;
}
Crystal Clear app kscreensaver.svg
Ausgabe:
7, 3.14159
Wenn du einen C++11-fähig Compiler hast, empfehle ich dringend für Konstruktor-Aufrufe immer folgende neue Syntax zu verwenden, außer du hast einen guten Grund, der die Syntax aus dem vorherigen Beispiel verlangt.
Nuvola-inspired-terminal.svg
#include <iostream>

struct A{
    A(int a):v1(a){}
    A(double a, int b):v1(b),v2(a){}

    int v1;
    double v2;
};

int main(){
    A o{3.14159, 7}; // alternativ: A o = {3.14159, 7};
    std::cout << o.v1 << ", " << o.v2 << std::endl;
}
Crystal Clear app kscreensaver.svg
Ausgabe:
7, 3.14159
Ein guter Grund wäre in diesem Fall beispielsweise die Initialisierung eines std::vector mit mit einer bestimmten Anzahl Elemente.
Nuvola-inspired-terminal.svg
#include <vector>

int main(){
    std::vector< int > v1{100}; // Vector mit einem Element, dass den Wert 100 hat
    std::vector< int > v2(100); // Vector mit hundert Elementen, die alle den Wert 0 haben -> hier sind Runde Klammern zwingend

    std::vector< int > v3{5, 8}; // Vector mit zwei Elementen, erstes mit dem Wert 5, Zweites mit dem Wert 8
    std::vector< int > v4(5, 8); // Vector mit fünf Elementen, die alle den Wert 8 haben -> hier sind Runde Klammern zwingend

    std::vector< int > v5{5, 8, 2}; // Vector mit drei Elementen, Prinzip is jetzt klar…
    std::vector< int > v6(5, 8, 2); // Compilierfehler, Konstruktor existiert nicht
}
Gruß --Prog 05:33, 31. Jan. 2013 (CET)[Beantworten]

Operator += prüft nicht ob maxlength überschritten wird (Operator Überladung)![Bearbeiten]

Siehe überschrift :)