Frage zu Vererbung (MFC)
-
Kurze Frage:
Leite von CButton eine Klasse ab. --> Klasse MyButton
Leite ebenfalls von CWnd ab. --> Klasse MyWnd
Nun, möchte jetzt, dass MyButton von MyWnd abgeleitet ist. Wie geht das?
Mein Ansatz war folgender (kompiliert nicht):
class MyButton : public CMyWnd, CButton
Das ist weniger gut, oder? Wie geht es besser?
-
Das sollte AFAIK schon gar nicht sooo schlecht sein..
wie wärs mit:
class MyButton : public CMyWnd, public CButton
ansonsten: was sagt der compiler?
mfg
tobi
-
lass mal das C bei CMyWnd weg, wenn deine Klasse MyWnd heisst...
-
Compiler meint folgendes:
MyButton.cpp(15) : error C2385: 'CMyButton::delete' is ambiguous MyButton.cpp(15) : warning C4385: could be the 'delete' in base 'CObject' of base 'CCmdTarget' of base 'CWnd' of base 'CMyWnd' of class 'CMyButton' MyButton.cpp(15) : warning C4385: or the 'delete' in base 'CObject' of base 'CCmdTarget' of base 'CWnd' of base 'CButton' of class 'CMyButton'
-
Also eigentlich ist das eine der verständlichsten Fehlermeldungen, die ich beim VC je gesehen habe.
(Okay, man muss wissen, dass ambiguous doppeldeutig heißt, aber dafür gibts ja dict.leo.org)
Hab mal für dich in die MSDN geguckt:
Compiler Error C2385
'class::member' is ambiguousThe specified member was derived from more than one object.
This error is caused by referencing a member of an object that was inherited from more than one object.
Make the member unambiguous by providing a cast or by changing the name of the offending members of the base classes.Warning C4385 is generated in conjunction with this error and provides additional information about the ambiguity.
The following is an example of this error:
struct A { int x; }; struct B { int x; }; struct C : A, B {}; void func () { C aC; aC.x = 9; // error }
-
Tja, Mehrfachmehrfachvererbung
MSDN: CObject |-CCmdTarget |-CWnd |-CButton
DU: CObject \ CCmdTarget | CWnd / \ CButton CMyWnd \ / CMyButton
Der Compiler weiß also nicht welche Funktion er nehmen soll, da diese mehrfach vorhanden sind.
Meine Lösung wäre nun, dass du alle Funktionen überschreibst die einen Fehler werfen und explizit deine gewünschte Basisklasse aufrufst.
-
Meine Vererbungsstruktur ist aber folgende:
CWnd / \ CMyWnd CButton \ / CMyButton
Geht aber nicht - laut Compiler.
-
Und wie bringe ich besagte Fehlermeldung weg?
-
Gib deiner Klasse eine Funktion "delete".
-
exakt, du musst delete überschreiben, sonst weis der compiler nicht, ob er CButton::delete() oder CMyWnd::delete() aufrufen soll.
-
Eine Funktion "delete" geben?
Hier nochmal der Code in ausführlicher.
class CMyWnd : public CWnd { public: CMyWnd(){}; virtual ~CMyWnd(){}; }; class CMyButton : public CMyWnd, public CButton { public: CMyButton(){}; virtual ~CMyButton(){}; };
Der Code bringt besagten Fehler hervor. Und was soll ich da jetzt noch hinzufügen?
-
Naja, du musst in die MSDN gucken, wie delete aussehen muss und fügst das in deine Klasse ein und ruft von da aus die Basisklasse (CWnd) auf.
class CMyButton : public CMyWnd, public CButton { public: CMyButton(){}; ~CMyButton(){}; void operator delete( void* p ); };
-
rewe schrieb:
Compiler meint folgendes:
MyButton.cpp(15) : error C2385: 'CMyButton::delete' is ambiguous MyButton.cpp(15) : warning C4385: could be the 'delete' in base 'CObject' of base 'CCmdTarget' of base 'CWnd' of base 'CMyWnd' of class 'CMyButton' MyButton.cpp(15) : warning C4385: or the 'delete' in base 'CObject' of base 'CCmdTarget' of base 'CWnd' of base 'CButton' of class 'CMyButton'
Bei CMyButton::delete weiß er nicht welches "delete" er aufrufen soll.
Oder besser, er weiß den Weg nicht.also
/* keine Ahnung */ CMyButton::delete(/* keine Ahnung */) { return CButton::delete( /* keine Ahnung */); }
-
OK. Danke vielmals! Habs kapiert. Und es funktioniert.
Wusste gar nicht, dass man delete überschreiben kann.
-
Du kannst ALLES (naja fast) überschreiben. Du musst nur wissen, wie der Prototyp aussieht.
D.h. du kannst auch eigene = != == < > << usw machen.
Und du kannst auch das Nutzen von bestimmten Funktionen aus den Basisklassen verbieten.
-
-
class CMyButton: public CMyWnd, public CButton { void* operator new(size_t nSize) {return malloc(nSize);}; void* operator new(size_t nSize, LPCSTR lpszFileName, int nLine){return malloc(nSize);}; void operator delete(void* p){ free(p); }; void operator delete(void *p, LPCSTR lpszFileName, int nLine){ free(p); };
Ist das so korrekt?