Zeiger von abgeleiteten Klassen mit gleicher Adresse



  • Vielen Dank erst mal für die schnellen Antworten.

    Wenn ich einen Vektor std::vector<Base *> erstelle und dort dann per Polymorphie verschiedene abgeleitete Objekte "reinstecke", dann kann ich mit dynamic_cast nur das abgeleitete Objekt bekommen, wenn es auch wirklich auf diese abgeleitete Klasse zeigt. Es wäre sehr bequem, wenn ich die Objekte in dem Vektor beliebig in andere Typen konvertieren könnte, allerdings so, dass ich trotzdem auf den gleichen Ort zeige und direkt darauf zugreifen kann. Ich halte es inzwischen allerdings unwahrscheinlich, dass das möglich ist.
    Ich werde es also so machen, wie ihr vorgeschlagen habt. Das ist natürlich ein wenig umständlicher.

    Decimad schrieb:

    Dieser Cast wird erst während der Laufzeit durchgeführt und ist natürlich ziemlich aufwendig, weil dafür für alle Objekte zur Laufzeit deren Typinformation benötigt wird und verglichen werden muss.

    Ich kenne den dynamic_cast erst seit kurzer Zeit und ich wollte mal fragen, ob es sich nun lohnt, ihn zu benutzen, da er ja anscheinend etwas Zeit verbraucht. Mit unionen, so würde ich vermuten, geht es schneller. Man muss dabei natürlich aufpassen, welche Variable man nun benutzt 🙂



  • King_Luc schrieb:

    Base b;
      Derived *pD;
      pD = &b;                     //dies gibt einen Fehler und soll nur grob verdeutlichen, was ich meine
    

    Polymorphie hat den Sinn, einen Zeiger oder eine Referenz auf eine Basisklasse zu haben, der/die generische Funktionalität besitzt. Das heisst, hinter dem Zeiger/der Referenz muss sich nicht umbedingt tatsächlich eine Basisklasse befinden; eine abgeleitete ist auch möglich. Was du versuchst, ist jedoch das Umgekehrte.

    King_Luc schrieb:

    Es wäre sehr bequem, wenn ich die Objekte in dem Vektor beliebig in andere Typen konvertieren könnte, allerdings so, dass ich trotzdem auf den gleichen Ort zeige und direkt darauf zugreifen kann. Ich halte es inzwischen allerdings unwahrscheinlich, dass das möglich ist.

    Du kannst die Zeiger schon so hinbiegen, dass sie auf irgendein Objekt zeigen. Nur führt das weder zu definiertem Verhalten noch hat es sonst einen Sinn.

    King_Luc schrieb:

    Ich kenne den dynamic_cast erst seit kurzer Zeit und ich wollte mal fragen, ob es sich nun lohnt, ihn zu benutzen, da er ja anscheinend etwas Zeit verbraucht. Mit unionen, so würde ich vermuten, geht es schneller. Man muss dabei natürlich aufpassen, welche Variable man nun benutzt 🙂

    Du solltest erst auf Performance achten, wenn du wirklich merkst, dass es nötig ist. Wie gesagt, benutze keine Unions in C++. Für Non-PODs geht das sowieso nicht, und selbst für PODs wirst du sie kaum brauchen.

    Unabhängig davon ist auch dynamic_cast nicht eine sehr schöne Lösung. Das meiste kann man mit virtuellen Funktionen erreichen.



  • Der dynamic-Cast ist ja etwas vollständig anderes als Unions. Bei Unions hast du unterschiedliche Objekte an ein und derselben Stelle zu unterschiedlichen Zeiten im Speicher während sich der Dynamic-Cast auf Klassenhierarchien bezieht. Unions verwendet man daher an Stellen, wo die einzelnen Objekte aber auch wirklich gar nichts miteinander zu tun haben (Und dann ist fraglich, warum sie überhaupt an einer Stelle stehen sollen), dynamic_cast's, wo man, für ansonsten über Basisklassen angesprochene Objekte, irgendwann doch mal als Spezialfall eine Sonderbehandlung braucht (beispielsweise um dynamische Dinge benutzerfreundlicher darzustellen, ohne die Basisklassenschnittstelle für einen Typ unnötig aufzuplustern. Naja, zumindest handhabe ich das so 😉
    Während du einen Zeiger durch eine Klassenhierarchie castest, bleibt der Zeiger vom Wert her (also der Addresse im Speicher) nicht zwangsweise (oder eher selten) gleich!



  • King_Luc schrieb:

    Es wäre sehr bequem, wenn ich die Objekte in dem Vektor beliebig in andere Typen konvertieren könnte, allerdings so, dass ich trotzdem auf den gleichen Ort zeige und direkt darauf zugreifen kann.

    Da stellt sich doch erstmal die Frage, warum die Objekte dann überhaupt von verschiedenen Klassen sind. Wenn die Objekte einander so ähnlich sind, daß sie beliebig hin- und herkonvertiert werden können, warum gehören sie dann nicht auch alle zu ein und derselben Klasse?



  • King_Luc schrieb:

    Ich habe eine Klasse von einer anderen abgeleitet und nun von der abgeleiteten Klasse einen Zeiger erstellt. Diesen möchte ich nun auf ein Objekt der Basisklasse zeigen lassen, wobei ich auch nur die Eigenschaften der Basisklasse benutzen möchte. Der Zeiger soll vollen Zugriff auf die Funktionen und Variablen des Objekts der Basisklasse besitzen.

    Dies geht grundsätzlich nicht, und macht auch keinen Sinn. Das hat alleine schon mit dem Speicherlayout zu tun. Wenn du ein Objekt der Basisklasse auf einen Zeiger auf eine davon Abgeleitete Klasse umbiegst (C-Cast und reinterpret_cast sollten das an sich ermöglichen), so ist ein Zugriff auf diesen Zeiger schlicht und ergreifend kritisch zu nennen.

    Was soll bitteschön passieren, wenn du auf eine Methode/Member zugreift die nicht zu der Basisklasse gehört? Das Verhalten ist undefiniert. Es könnte deine Festplatte formatieren, einfach nur einen dahinterliegenden Speicherbereich als Wert interpretieren...

    Basisklassen dienen nicht dazu auf untergeordnete Klassen zu verweisen, sondern um als gemeinsame Schnittstelle von davon abgeleiteten zu dienen.

    Davon abgesehen noch ein paar andere Punkte:
    a) Zugriffsmodifikatoren hast du wohl in der Eile vergessen (public:...)
    b) Ich würde Membervariablen möglichst nicht öffentlich deklarieren, selbst Setter/Getter die nichts anderes als den Zugriff weiterleiten haben einen Vorteil: Du kannst später noch einen Zugriffsschutz oder Bereichsüberprüfungen ohne große Codeänderung einfügen.
    c) Basisklassen sollten im Regelfall immer über einen virtuellen Destruktor verfügen.

    cu André



  • asc schrieb:

    c) Basisklassen sollten im Regelfall immer über einen virtuellen Destruktor verfügen.

    ... wenn sie in polymorphen Kontexten benötigt werden. 😉



  • Nexus schrieb:

    asc schrieb:

    c) Basisklassen sollten im Regelfall immer über einen virtuellen Destruktor verfügen.

    ... wenn sie in polymorphen Kontexten benötigt werden. 😉

    Was zumindestens bei mir der Regelfall ist (und ansonsten sollte man wenigstens die Regel mit dem private-Konstruktor einhalten, den unbedachtes "Vergessen" ist nicht unüblich...).



  • drakon schrieb:

    Wenns unbedingt sein muss, machste halt ein Cast..

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-229749.html

    🙄 🙄



  • Ok ich werd's jetzt ganz normal über Polymorphie machen.
    Am Anfang hatte ich nur eine Klasse, was natürlich kein Problem war. Da ich aber meistens von diesem Typ nur grundlegende Variablen und Funktionen benutzt habe, habe ich noch eine Basisklassse erstellt, die wirklich nur diese paar Variablen erhählt, um nicht so viel Speicher zu verbrauchen. Daraus ergab sich das Problem mit dem Vektor. Ein Freund von mit hat mir Union vorgestellt, was mir da als eine ganz sinnvolle Möglichkeit hielt (ich kannte den dynamic_cast noch nicht). Anscheinend sind diese wohl nicht sinnvoll, also muss ich mein Programm umwandeln.

    Inzwischen ist mir aufgefallen, dass es nicht viel aufwendiger ist, und dass es wirklich keinen Sinn hat, teilweise auf Eigenschaften eines Objekts zugreifen zu wollen, die dieses eigentlich nicht besitzt.

    Danke für die vielen und hilfreichen Antworten!



  • .
    (EDIT: hat sich erledigt - hätte erstmal das letzte posting lesen sollen *pfeiff*)



  • mammamia;


Anmelden zum Antworten