Initialisierungsliste bei const Member !



  • class MoneyEUR {
    const double EURValue;
    const double USValue;
    const double rate;
    public:
    MoneyEUR (double _USvalue, double _rate)
    {
    };
    };
    

    kann ich folgenden Code so vervollständigen :

    MoneyEUR (double _USvalue, double _rate) : USValue(_USValue), rate(_rate),EURValue(_USvalue/_rate)
    


  • Gegenfrage:

    Bacid90210 schrieb:

    class MoneyEUR {
    const double EURValue;
    const double USValue;
    const double rate;
    

    Wozu soll das gut sein? Macht das wirklich Sinn, hier const zu verwenden? Ich halte das für sehr unwahrscheinlich

    kk



  • Bacid90210 schrieb:

    class MoneyEUR {
    const double EURValue;
    const double USValue;
    const double rate;
    public:
    MoneyEUR (double _USvalue, double _rate)
    {
    };
    };
    

    kann ich folgenden Code so vervollständigen :

    MoneyEUR (double _USvalue, double _rate) : USValue(_USValue), rate(_rate),EURValue(_USvalue/_rate)
    

    Falsche Reihenfolge der Initialisierung.



  • krümelkacker schrieb:

    Wozu soll das gut sein? Macht das wirklich Sinn, hier const zu verwenden? Ich halte das für sehr unwahrscheinlich

    Wenn er einen einzelnen Kurseintrag als konstant ansieht, spricht nichts dagegen (Dann muss er aber immer wieder neue Instanzen bei geänderten Kursen anlegen).

    Bacid90210 schrieb:

    kann ich folgenden Code so vervollständigen :

    MoneyEUR (double _USvalue, double _rate) : USValue(_USValue), rate(_rate),EURValue(_USvalue/_rate)
    

    Ja, wobei ich aber grundsätzlich dazu raten würde, die Initialisierungsliste in der gleichen Reihenfolge wie in der Memberdeklaration zu halten. Den, unabhängig welche Reihenfolge du in der Initialisierungsliste angibst, erfolgt die Initialisierung in Reihenfolge der Member. Da du hier nur auf die Parameter zugreifst mag es unproblematisch sein, aber wehe du hättest EURValue mit den später deklarierten USValue und rate initialisiert.



  • Wenn man Konstanten benötigt, die über die Lebenszeit einer Instanz gültig sind, macht das durchaus Sinn.
    Aus Beispiel fällt mir eine Printer-Konfiguration ein, die für ihre Lebenszeit ( also all die Druckaufträge, die mit dieser Konfiguration gedruckt werden sollen ) einige Parameter nicht verändern soll beziehungsweise darf.
    Und wenn einem die Sprache so etwas frei Haus liefert, warum das dann nicht auch benutzen?

    Gruß Kimmi



  • kimmi schrieb:

    Und wenn einem die Sprache so etwas frei Haus liefert, warum das dann nicht auch benutzen?

    Weil es einen in manchen Fällen unnötig einschränkt. Zum Beispiel kann man das Objekt nicht mehr in STL-Containern speichern und nicht mehr swappen. Die Konstanz erreicht man ohne diese Nachteile auch, indem man nur Getter anbietet.

    Wenn alle Datenmember einer Klasse const -qualifiziert sind, könnte man auch darüber nachdenken, einzelne Instanzen zu qualifizieren.



  • Bacid90210 schrieb:

    class MoneyEUR {
    const double EURValue;
    const double USValue;
    const double rate;
    public:
    MoneyEUR (double _USvalue, double _rate)
    {
    };
    };
    

    kann ich folgenden Code so vervollständigen :

    MoneyEUR (double _USvalue, double _rate) : USValue(_USValue), rate(_rate),EURValue(_USvalue/_rate)
    

    Nein. Nicht nur ist die Reihenfolge falsch. _USValue etc. ist als Name nicht erlaubt. http://www.c-plusplus.net/forum/viewtopic-var-t-is-39461.html

    Aber es ist übrigens kein Problem die Parameter wie die Member zu benennen.

    MoneyEUR(double USValue, double rate) : USValue(USValue), rate(rate) { }
    


  • Nexus schrieb:

    kimmi schrieb:

    Und wenn einem die Sprache so etwas frei Haus liefert, warum das dann nicht auch benutzen?

    Weil es einen in manchen Fällen unnötig einschränkt. Zum Beispiel kann man das Objekt nicht mehr in STL-Containern speichern und nicht mehr swappen. Die Konstanz erreicht man ohne diese Nachteile auch, indem man nur Getter anbietet.

    Wenn alle Datenmember einer Klasse const -qualifiziert sind, könnte man auch darüber nachdenken, einzelne Instanzen zu qualifizieren.

    Das wäre in der Tat auch eine Idee. Und mir war nicht bewusst, daß man bei Const-Member-Initialisierungen Probleme mit STL-Containern bekommt. Wieder etwas gelernt.

    Gruß Kimmi



  • kimmi schrieb:

    Und mir war nicht bewusst, daß man bei Const-Member-Initialisierungen Probleme mit STL-Containern bekommt. Wieder etwas gelernt.

    Das Problem liegt mehr beim Zuweisungsoperator, der beim Vorhandensein von const -Membern (oder Referenzen) nicht mehr automatisch generiert wird und auch vom Benutzer nicht ohne Hacks implementiert werden kann. STL-Container erfordern aber, dass der gespeicherte Typ kopier- und zuweisbar ist.



  • Dann wäre es also nur möglich, Pointer auf die Instanz mit Const-Attributen in einem STL-Container zu halten, da dort die Instanz nicht kopiert wird, sondern halt nur der Pointer. Gut zu wissen, das war mir bisher nicht bewußt. Danke!

    Gruß Kimmi



  • Genau, bei nichtkopierbaren (oder polymorphen) Objekten sind Zeiger auch das übliche Vorgehen, um mehrere Objekte gemeinsam in Containern zu speichern. Wobei es sich wegen Exceptionsicherheit und Speicherverwaltung empfiehlt, anstelle der STL-Container dafür spezialisierte Klassen – z.B. aus der Boost.PointerContainer-Bibliothek – zu verwenden.


Log in to reply