Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Problem mit "virtual"

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
12.06.2005, 07:55 Uhr
~DarthDevilous
Gast


Hier ein paar Ausschnitte aus meinem Code:


C++:
#define DECLARE_OBJECT(class_name) \
public: \
   static const CRuntimeClass class##class_name; \
   virtual CRuntimeClass* GetRuntimeClass() const; \

#define IMPLEMENT_OBJECT(class_name, base_class_name) \
   const CRuntimeClass class_name::class##class_name( \
   #class_name, _RUNTIME_CLASS(base_class_name), Alloc##class_name); \
   CRuntimeClass* class_name::GetRuntimeClass() const \
       { return _RUNTIME_CLASS(class_name); } \

Object::Object(const char *lpszName/*=NULL*/)
: pChildObject(NULL), pParentObject(NULL), pNextObject(NULL), bActive(false)
{
   // Kein Name angegeben, es muss eins generiert werden
   if (lpszName == NULL)
   {
       *const_cast<std::string*>(&strName) = GetRuntimeClass()->GetClassName();
       char szObjectCount[16];
       ultoa(GetRuntimeClass()->GetNextIndex(), szObjectCount, 10);
       const_cast<std::string*>(&strName)->append(szObjectCount);
   }
   // Den angegebenen Namen übernehmen
   else
       *const_cast<std::string*>(&strName) = lpszName;
}

class String : public Object
{
   DECLARE_OBJECT(String)
public:
   String(const char *lpszName = NULL)
   : Object(lpszName) { }
}

IMPLEMENT_OBJECT(String, Object)



Das Problem liegt darin, dass der Object-Konstruktor, vom String-Konstruktor gerufen, mit GetRunteimClass() sein eigner RuntimeClass und nicht den vom String holt. Wiso? GetRuntiemClass ist ja als virtual deklariert, es sollte doch das vom String gerufen werden???
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
12.06.2005, 09:55 Uhr
(un)wissender
Niveauwart


Das wirst du so nicht lösen können, da virtuelle Funktionen während der hierachischen Basisobjekterstellung nicht virtuell sind. Will heißen, sie verhalten sich wie nicht-virtuelle Methoden.

Noch ein paar Anmerkungen:

1. Dein const-cast ist nicht gut und vermutlich gefährlich. Das muss so nicht sein.
2. Warum DECLARE_OBJECT? Einfach in Object integrieren, dass ist der saubere Weg. Kein Macro mehr und der Anwender muss auch nichts mehr schreiben.
3. IMPLEMENT_OBJECT, wieder ein Macro. Gibt es da noch was anderes?
--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 12.06.2005 um 09:56 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
12.06.2005, 14:24 Uhr
~DarthDevilous
Gast


Zu den Anmerkungen:
der Object::strName ist ein const std::string, und der const_cast wird nur im Konstruktor benutzt, zum initialisieren von strName.
Das mit dem DECLARE_OBJECT und IMPLEMENT_OBJECT ist da weil es möglichst einfach sein soll, weitere Klassen in die Klassenhierarchie einzufügen, und ein zugehöriges CRuntimeClass zu diesen Klassen zu erstellen.

Und zur antwort auf meine Frage: Das wohl offensichtlichste währe, nochmals ein Macro zu definieren mit der Inizialisierung, aber hier Stimme ich zu dass das doch eine sehr unschöne Lösung ist. Ist die Regel, die du geschrieben hast, nur für den Konstruktor gültig? D.h., wäre es möglich eine private Funktion von Object zu definieren, welche auf den richtigen GetRuntimeClass zugreift (also den von String), und dann diese Funktion von Object::Object aus zu rufen? Oder würde das zum gleichen Resultat führen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
12.06.2005, 15:20 Uhr
(un)wissender
Niveauwart


Würde natürlich zum gleichen Resultat führen. Übrigens, virtuelle Methoden in Destruktoren sind auch nicht ungefährlich.

Zum const_cast: den kannste vermeiden, nutze den ternären Operator in der Initialisierungliste zur Zuweisung von strName.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: