Basisinitialisierer Vererbung



  • @C-Sepp sagte in Basisinitialisierer Vererbung:

    kommt hingegen ein Fehler. Warum? Vielen Dank!

    Welcher denn?

    Und: beantworte mal meine Frage zu Zeile 14 im vorherigen Post. Wenn du die sinnentnehmend weiter auf die Zeile 7 in dem Parcel-Code anwendest, solltest du deine Lösung haben.



  • Da kommt der Fehler:
    error C2664: "Parcel::Parcel(int,float,Address &,bool,Address)" : Konvertierung von Argument 3 von "Address" in "Address &" nicht möglich
    Stimmt, das fällt ja unter den Punkt Const-Correctness. Wie meinst du das?



  • Stimmt, das fällt ja unter den Punkt Const-Correctness. Wie meinst du das?

    Genau so habe ich das gemeint! Du hast hiermit doch das Problem schon erkannt. Dann sollte "Problem gebannt" doch nur 1 Schritt entfernt sein! Ein temporäres Objekt kann halt nicht an eine non-const-Referenz binden (alle Änderungen an dem Objekt wären ja auch für die Katz).



  • Leider doch noch nicht ganz. Du hattest ja geschrieben dass ein temporäres Objekt nicht an eine non-const-Referenz gebunden werden kann. Warum ist das so...aus den Artikel: https://www.c-plusplus.net/forum/topic/39474/referenz-auf-ein-temporäres-objekt/12
    bin ich nicht schlau geworden. Und warum erzeugt Adress() ein temporäres Objekt und adr dann nicht. Beide befinden sich doch im Konstruktor der Klasse TraceParcel und sollte demzufolge über die Lebensdauer eines Objektes vom Typ TraceParcel existieren und demzufolge temporär sein? Danke!



  • Temporär bedeutet, daß ein Objekt direkt erzeugt wird, aber nach dem Aufruf nicht weiter verwendet wird (bzw. kann, weil es keiner Variablen zugewiesen ist).
    Und genau das ist bei Address() der Fall, während bei dem Parameter adr ja ein benanntes Objekt vorliegt (und der Compiler dann davon ausgeht, daß der Programmierer dies bewußt so erzeugt hat).

    Würde die Basisklasse Mail den Parameter ebenfalls als Referenz entgegennehmen und sogar in einer Referenz-Membervariablen halten, dann würde zwar auch kein Compilerfehler erfolgen, aber da die Lebenszeit des übergebenen Parameters adr kürzer als die Lebenszeit des Klassenobjekts wäre, dürfte danach (d.h. nach dem Konstruktor) nicht mehr über die gespeicherte Referenz darauf zugegriffen werden (UB).

    PS: Ich vermisse @HumeSikkins hier - er hat viel zum C++ Forum beigetragen und besonders auch seine eigene C++ Webseite (an deren genauen Namen ich mich nicht mehr erinnere: C++ FAQ oder s.ä.).



  • Aber sowohl Address() als auch adr werden doch den Referenzparameter t des Basisintialisierer zugewiesen und in den Fall verwendet? Trotzdem sind nicht beide temporäre Objekte. Irgendwie ist mir das noch nicht ganz klar.
    Nach Lesen des Beitrages von HumeSikkins muss man also einfach dass laut C++-Standard eine nicht konstante Referenz keinen temporären Objekt zugewiesen werden kann, ohne das zu hinterfragen?



  • Jetzt ist es klar...eigentlich habt ihr ja schon alles geschrieben. Nochmals vielen Dank!

    @Th69 : Zu Lebenszeiten von temporären Objekten die an eine Memberreferenz gebunden sind, habe ich einen
    weiteren guten Artikel gefunden. Darin steht:
    "
    Shlo 16. Aug. 2004, 01:43
    Laut dem Standard, bleibt eine temporäres Objekt, das an eine Referenz gebunden wird, bestehen bis die Referenz zerstört wird, außer - das temporäre Objekt wird in der Initialisierungsliste eines Konstruktors an eine Member-Referenz gebunden oder an einen Funktionsparameter. Dann endet die Lebendsdauer des Objekts mit dem Ablauf des Konstruktors bzw. der Funktion.
    "
    (https://www.c-plusplus.net/forum/topic/82903/lebensdauer-eines-temporären-objekts)

    Dies würde deiner Aussage von vor 4 Tagen ("...aber da die Lebenszeit des übergebenen Parameters adr kürzer als die Lebenszeit des Klassenobjekts wäre, dürfte danach (d.h. nach dem Konstruktor) nicht mehr über die gespeicherte Referenz darauf zugegriffen werden) doch eigentlich widersprechen?



  • Der Beispielcode aus dem Post ist wichtig. Das temporäre Objekt wird an eine const Referenz gebunden, dass ist in C++ erlaubt und verlängert die Lebenszeit des Objektes auf die Lebenszeit der const Referenz.



  • Ja genau...also ist die Aussage von vor 4 Tagen verkehrt



  • Nein, da in deinem Code

    TraceParcel(const Parcel& pc, Address adr): Parcel(1, 2, adr )
    

    adr als Wert übergeben wird (d.h. es wurde eine Kopie erzeugt).
    Reichst du diese als Referenz an die Basisklasse Parcel weiter (und wie schon geschrieben, würde diese Referenz dann gespeichert werden), so wird adr nach Verlassen des Konstruktor wieder zerstört und die gespeicherte Referenz referenziert ins Nirvana.

    Und selbst bei Address& adr wäre dies entsprechend so:

    ... außer - das temporäre Objekt wird in der Initialisierungsliste eines Konstruktors an eine Member-Referenz gebunden. Dann endet die Lebensdauer des Objekts mit dem Ablauf des Konstruktors ...


Anmelden zum Antworten