Objekttyp zur Laufzeit festlegen



  • daersc schrieb:

    noch eine Frage: muss das ein Pointer sein?

    Ja, das ist die einzige Möglichkeit, Objekte dynamisch zu erzeugen. Wenn du "normal" ein Objekt erzeugst (z.B. mit " A a; "), muss die Größe zur Zeit des Kompilierens bekannt sein. Da aber zur Compile-Zeit noch nicht klar ist, welches Objekt es wird, muss man auf dynamische Erzeugung mittels "new" zurückgreifen, was einen Pointer zurückliefert 🙂



  • Badestrand schrieb:

    daersc schrieb:

    noch eine Frage: muss das ein Pointer sein?

    Ja, das ist die einzige Möglichkeit, Objekte dynamisch zu erzeugen. Wenn du "normal" ein Objekt erzeugst (z.B. mit " A a; "), muss die Größe zur Zeit des Kompilierens bekannt sein. Da aber zur Compile-Zeit noch nicht klar ist, welches Objekt es wird, muss man auf dynamische Erzeugung mittels "new" zurückgreifen, was einen Pointer zurückliefert 🙂

    Ich hab's mal so probiert:

    if (...) obj = new A();
    else if (...) obj = new B();
    else if (...) obj = new C();
    else obj = new BASE();
    
    BASE& obj_ref = *obj;
    

    obj_ref lässt sich wie eine normale variable verwenden.
    bekomm ich damit mal probleme, wenn sich zum beispiel die adresse von obj ändert?



  • daersc schrieb:

    bekomm ich damit mal probleme, wenn sich zum beispiel die adresse von obj ändert?

    wie will sich die addresse eines objektes zur laufzeit ändern? 🙂
    du meinst, wenn du das objekt löschst. dass gibt natürlich probleme.

    eine referenz ist intern ein zeiger (nicht vom standard bestätigt, aber wird
    von allen kompiliern so umgesetzt). außer einer anderen syntax ändert sich
    nichts.



  • ok 🙂

    #include <iostream>
    using namespace std;
    
    class BASE {
    };
    
    class A : public BASE {
    public:
      int foo() {return 123;} // Nur in A definiert
    };
    
    class B : public BASE {
    public:
      int bar() {return 456;} // Nur in B definiert
    };
    
    int main() {
      BASE* ptr = new A(); // Im Programm durch Auswahl ersetzen
      BASE& ref = *ptr;
    
      cout << "ref.foo(): " << ref.foo() << endl; // foo() aufrufen???
    }
    

    Geht nicht 😢



  • antwort schrieb:

    wie will sich die addresse eines objektes zur laufzeit ändern? 🙂

    die frage is aber nicht ernst gemeint? Oo

    T *a, *b;
    a = new T(1);
    b = new T(2);
    
    T &a_ = *a;
    a_.Get();//1
    std::swap (a, b);
    a_.Get();//2
    

    bb

    edit:

    class BASE { 
    public:
     virtual void foo() = 0;
    };
    

    jz sollte es gehen ^^

    btw:

    int main() { 
      BASE* ptr = new A(); // Im Programm durch Auswahl ersetzen 
      BASE& ref = *ptr; 
    
      cout << "ref.foo(): " << ref.foo() << endl; // foo() aufrufen??? 
    delete ptr; //!
    }
    


  • unskilled schrieb:

    class BASE { 
    public:
     virtual void foo() = 0;
    };
    

    jz sollte es gehen ^^

    aber das heißt doch, dass alle Ableitungen diese Funktion definieren müssen oder?



  • Ja, genau das heißt es.
    Wenn die Funktion nur in A bekannt sein soll, musst du wohl oder übel casten (zur Sicherheit evtl. dynamic_cast).



  • Braunstein schrieb:

    Ja, genau das heißt es.
    Wenn die Funktion nur in A bekannt sein soll, musst du wohl oder übel casten (zur Sicherheit evtl. dynamic_cast).

    ach das geht auch zur abgeleiteten klasse hin?
    ich glaub ich les noch mal in aller ruhe etwas literatur zu diesen dingen 😉



  • daersc schrieb:

    ach das geht auch zur abgeleiteten klasse hin?

    Das ist der hauptsächliche (und evtl. einzige) Sinn des dynamic_cast. Einen sicheren Downcast zu gewährleisten.
    Du kannst ja mal in der FAQ nachschauen. Da steht auch was dazu.



  • Zweite Seite, und es hat tatsächlich noch niemand etwas von virtuellen Funktionen erwähnt?



  • Nexus schrieb:

    Zweite Seite, und es hat tatsächlich noch niemand etwas von virtuellen Funktionen erwähnt?

    doch?



  • unskilled schrieb:

    T *a, *b;
    a = new T(1);
    b = new T(2);
    
    T &a_ = *a;
    a_.Get();//1
    std::swap (a, b);
    a_.Get();//2
    

    sehr schön. du hast erfolgreich zwei zeiger auf objekte geändert.
    das objekt selber ist immernoch da wo es erzeugt wurde, wenn auch unter
    anderem namen.

    wo kommen wir den dahin dass die objekte jetzt von selber durch den speicher
    wandern?? hiiiiiilfe! 😛



  • unskilled schrieb:

    doch?

    Dachte ich doch. Dabei hatte ich extra noch kurz mit der Seitensuche gesucht... Sorry in diesem Fall. 🙂



  • antwort schrieb:

    unskilled schrieb:

    T *a, *b;
    a = new T(1);
    b = new T(2);
    
    T &a_ = *a;
    a_.Get();//1
    std::swap (a, b);
    a_.Get();//2
    

    sehr schön. du hast erfolgreich zwei zeiger auf objekte geändert.
    das objekt selber ist immernoch da wo es erzeugt wurde, wenn auch unter
    anderem namen.

    wo kommen wir den dahin dass die objekte jetzt von selber durch den speicher
    wandern?? hiiiiiilfe! 😛

    verdammt - ich wollte iter_swap() nehmen - aber iwie hab ich aus gewohnheit dann doch swap() genommen - und damit hab ich mein schönes bsp kaputt gemacht 😉

    Nexus schrieb:

    unskilled schrieb:

    doch?

    Dachte ich doch. Dabei hatte ich extra noch kurz mit der Seitensuche gesucht... Sorry in diesem Fall. 🙂

    np ^^

    bb


Anmelden zum Antworten