Gegenseitige Referenz


  • Mod

    LordJaxom schrieb:

    @HumeSikkins:

    Danke für den Link, aber das war mir schon klar, dass das entweder eine Copyconstruction aus einem Temporary oder eine Construction unter eliminierung des Temporary sein muss (falsch ausgedrückt).

    Was mir jedoch nicht klar war, war dass man auf diesem Wege das Temporary eliminieren UND auf den zu initialisierenden Bezeichner zugreifen kann. Wenn ich das richtig verstehe kann man die Zeile

    A a = *new B("Fred", a);
    

    weder durch die direkte Initialisierung

    A a( *new B("Fred", a) );
    

    noch durch die Copy-Initialisierung via Temporary

    A temp( *new B("Fred", <nix da>) );
    A a( temp );
    

    äquivalent darstellen. Ich dachte immer die Copy-Initialisierung ist zu mindestens einem dieser beiden äquivalent. Aber man lernt bekanntlich nie aus 😉

    kommt darauf an, was du mit äquivalent meinst. jedenfalls führt die direkte initialisierung zum selben ergebnis. unterschiede könnten sich nur ergeben, wenn bei copy-initialisierung ein temporary erzeugt wird und das irgendwelche seiteneffekte zur folge hat. du könntest ja auch

    A a( A( *new B("Fred", a) ) );
    

    schreiben 🙂



  • MSVC++2005 sagt sowohl zu

    A a( A( *new B("Fred", a) ) );
    

    als auch zu

    A a( *new B("Fred", a) );
    

    MSVC++2005 schrieb:

    error C2065: 'a' : undeclared identifier

    😕

    Nur die Copy-Initialisierung per Zuweisung wird akzeptiert.


  • Mod

    stimmt, ja. da war ich wohl selbst ein wenig konfus.

    camper schrieb:

    ein bezeichner gilt als deklariert unmittelbar nach dem letzten deklarator (insbesondere vor seinem initialisierer).

    ist ja nur die halbe wahrheit. der initialisierer ist ja selbst ein deklarator und regel lautet

    3.3.1/1 The point of declaration for a name is immediately after its complete declarator (clause 😎 and before its
    initializer (if any), except as noted below.

    (für die diskussion unwesentliche absätze mit ausnahmen folgen)



  • wie kann man sich nur seitenweise darüber unterhalten wie man ein so schlechtes design umsetzen kann..



  • Eine Referenz ist intern ein derefrenzierter Zeiger, A* a; A& = *a;

    struct B;
    struct A
    {
        B* b;
        B& my_B;
        A(B* b);
    };
    struct B
    {
        A* a;
        A& my_A;
        B(A* a);
    };
    A::A(B* b) : b(b), my_B(*b){ if (b) b->a = this; }
    B::B(A* a) : a(a), my_A(*a){ if (a) a->b = this; }
    
    int main()
    {
      A h(0); //Null-Zeiger struct B existiert noch nicht 
      B m(&h);//Referenz auf h wird gebildet 
              //und h erhält eine Referenz auf m von m. 
    }
    

    mfg


  • Mod

    Helmut S. schrieb:

    Eine Referenz ist intern ein derefrenzierter Zeiger, A* a; A& = *a;

    struct B;
    struct A
    {
        B* b;
        B& my_B;
        A(B* b);
    };
    struct B
    {
        A* a;
        A& my_A;
        B(A* a);
    };
    A::A(B* b) : b(b), my_B(*b){ if (b) b->a = this; }
    B::B(A* a) : a(a), my_A(*a){ if (a) a->b = this; }
    
    int main()
    {
      A h(0); //Null-Zeiger struct B existiert noch nicht 
      B m(&h);//Referenz auf h wird gebildet 
              //und h erhält eine Referenz auf m von m. 
    }
    

    mfg

    undefiniertes verhalten.



  • camper schrieb:

    ...undefiniertes verhalten.

    Und das ist noch optimistisch betrachtet - ich würde auf eine Speicherschutzverletzung tippen:

    Helmut S. schrieb:

    ...

    ...
    A::A(B* b) : b(b), my_B(*b)... // Hier wird (mit u.a. Code) 0 dereferenziert
    
    int main()
    {
      A h(0); 
    ...
    

    mfg

    OK, bei der Initialisierung einer Referenz muß der Compiler vielleicht nicht unbedingt dereferenzieren, aber alternativ wird er eben den hinter der Referenz stehenden Pointer auf "0" setzen .... was dann beim ersten Zugriff auf die Referenz den entsprechenden Fehler gibt.

    Gruß,

    Simon2.


Anmelden zum Antworten