Zugriff auf __interface-Methoden
-
item ist statisch vom Typ void*. Zur Laufzeit finden sich darin Subklassen von TControl. Ich habe jetzt folgendes versucht:
void* item = TabOrderListe->Items[IndexActiveControl]; IFocusInfo* FocusInfo = dynamic_cast<IFocusInfo*>(item);Ergibnis: Selber Compiler-Fehler ("E2307 Typ 'void' ist keine definierte Klasse bei virtuellen Funktionen")
-
Achso, ja das kann nicht gehen. Ich weiß zwar jetzt nicht, ob der Standard das verlangt, aber zumindest Borland verlangt, dass ein Typ virtuelle Funktionen hat, damit man ihn dynamic_casten kann.
-
Das kann aber auch nicht die Wurzel des Problems sein. Ich hab' jetzt 'mal folgendes probiert (Änderungen fett):
void __fastcall TForm1::EditWf1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { TList* TabOrderListe = new TList(); GetTabOrderList(TabOrderListe); int IndexActiveControl = TabOrderListe->IndexOf(ActiveControl); [b]IFocusInfo* FocusInfo = dynamic_cast<IFocusInfo*>(Controls[IndexActiveControl]);[/b] int I = IndexActiveControl; while(!FocusInfo->GetFocusErlaubt()) // Hier tritt die Zugriffsverletzung auf. { if(I < TabOrderListe->Count - 1) { I++; } else { I = 0; } FocusInfo = (IFocusInfo*)TabOrderListe->Items[I]; } ActiveControl = (TWinControl*)FocusInfo; }Das wäre zwar ein semantischer Fehler müsste beim Kompilien aber durchlaufen, wenn es daran liegen würde, denn die Elemente von "Controls" sind vom Typ TControl* und das hat ja virtuelle Funktionen.
Es kommt aber der Fehler "E2031 Typumwandlung von 'TControl *' nach 'IFocusInfo *' nicht zulässig"
Gruß
Marc
-
Hat wirklich keiner eine Idee dazu? Es kann doch nicht sein, dass noch nie jemand versucht hat, über eine Schnittstelle auf ein Objekt zuzugreifen.
Auch mit der Information, dass es definitiv nicht geht wäre mir notfalls geholfen, dann müsste ich mir keine Gedanken mehr darüber machen, was ich falsch mache.Gruß
Marc
-
Hallo,
1. TList::Items ist vom Typ void*. Das kannst du natürlich nicht mit einem dynamic_cast in deinen gewünschten Typ umwandeln. Entweder den (schon von dir verwendeten C-Cast) oder einen reinterpret_cast.
2. Du sagst, dass dein TList Objekte vom Typ TControl enthält. Das kannst du ja schwerlich nach IFocusInfo casten da die beiden Klassen ja nicht in einer Vererbungshierarchie stehen. Vielleicht geht ja ein cast nach TEditWf.
3. Mehrfachvererbung mit VCL-Klassen stellt normalerweise ein Problem dar, da VCL-Klassen in Pascal geschrieben sind und Pascal nunmal keine Mehrfachverebung unterstützt. Allerdings ist bei dir nur eine VCL-Klasse (TEdit) beteiligt. Da weiß ich nicht genau ob das gerade noch geht.
4. Dir ist klar das das Schlüsselwort __interface in C++ eigentlich nicht existiert? Hier (im BCB) ist es lediglich ein define auf class
Ciao
-
Hallo
3. Mehrfachvererbung mit VCL-Klassen stellt normalerweise ein Problem dar, da VCL-Klassen in Pascal geschrieben sind und Pascal nunmal keine Mehrfachverebung unterstützt. Allerdings ist bei dir nur eine VCL-Klasse (TEdit) beteiligt. Da weiß ich nicht genau ob das gerde noch geht.
Nein, Mehrfachvererbung ist in keinem Fall mit VCL-Klassen möglich :
E2278 VCL-Klassen dürfen nicht mehrere Basisklassen haben
bis bald
akari
-
Das ist schon richtig, aber ist die neue Klasse denn überhaupt eine VCL-Klasse? Wir sind jetzt ja immerhin in C++.
Mich hat es nur gewundert, dass er hier eine Zugriffsverletzung bekommt. Wenn die Mehrfachvererbung nicht ginge hätte doch eigentlich schon der Compiler meckern müssen.
-
Hallo
die Fehlermeldung habe ich bei diesem Test bekommen :
class N { public : N() {}; }; class Test : public TEdit, public N { public : Test() : TEdit(NULL), N() {}; };bis bald
akari
-
akari schrieb:
Mehrfachvererbung ist in keinem Fall mit VCL-Klassen möglich
Jein. Mehrfache Schnittstellenvererbung geht auch mit VCL-Klassen (so ähnlich wie in Java).
Also z.B. sowas:class MeinInterface { public: virtual void meineReinVirtuelleMethode() = 0; __property int EineEigenschaft = {read=getEineEigenschaft, write=setEineEigenschaft}; protected: virtual int getEineEigenschaft() = 0; virtual void setEineEigenschaft(int Value) = 0; }; class MeineVCLKlasse: public TComponent, public MeinInterface { public: // Konstruktor, Destruktor... virtual void meineReinVirtuelleMethode(); protected: virtual int getEineEigenschaft(); virtual void setEineEigenschaft(int Value); };Das Beispiel sollte sich kompilieren lassen (obwohl ich's nicht ausprobiert habe).
Wenn man Komponenten im Designer visuell miteinander verbinden will (über den Objektinspektor),
müssen die Komponenten natürlich auch von TComponent erben.Gruß,
Alexander
-
Hallo
Das Beispiel sollte sich kompilieren lassen (obwohl ich's nicht ausprobiert habe).
Also ich habe dein Beispiel kopiert und es kommt ebenfalls die von mir bereits gepostete Fehlermeldung.
Muß da noch irgendwas eingestellt/geändert werden?bis bald
akari
-
akari schrieb:
Also ich habe dein Beispiel kopiert und es kommt ebenfalls die von mir bereits gepostete Fehlermeldung.
Muß da noch irgendwas eingestellt/geändert werden?Ich verwende Schnittstellenvererbung mit VCL-Klassen an einigen Stellen, allerdings mit TForm und TObject,
mit TComponent habe ich das noch nie probiert. Allerdings wüsste ich nicht, was dagegen sprechen sollte.
Welche BCB-Version verwendest Du denn?Gruß,
Alexander
Edit: Habe mal meinen Code in die Header-Datei des automatisch erstellten Formulars eines neuen Projekts kopiert
und bei mir wird das einwandfrei kompiliert.
-
Kann es sein, dass es an der BCB-Variante liegt. In diesem Thread http://www.c-plusplus.net/forum/viewtopic.php?t=48437&highlight=mehrfachvererbung wird gesagt, dass der BCB6 damit zurechtkommt.
-
Hallo
ich benutzte BCB 5.01. Dann liegt es wohl daran.
Denn das letzte Beispiel aus Braunsteins Link führt ebenfalls zu der Fehlermeldung. Wenn das bei euch mit V6 auch funktioniert, ist es klar.bis bald
akari
-
Braunstein schrieb:
Hallo,
2. Du sagst, dass dein TList Objekte vom Typ TControl enthält. Das kannst du ja schwerlich nach IFocusInfo casten da die beiden Klassen ja nicht in einer Vererbungshierarchie stehen. Vielleicht geht ja ein cast nach TEditWf.Nach TEditWf kann ich schon casten, nur bringt es mir nichts. Es soll ja später mehrere Komponenten geben, die IFocusInfo implementieren. Da ich beim Duchlauf durch die Liste nicht weiß, ob da an einem bestimmt Index ein TEditWf oder eine andere Komponente, die die Schnittstelle ebenfalls implementiert, steht, will ich nach IFocusInfo casten. (Wie man es in Java machen würde, richtig erkannt Alexander.)
Wenn ich mir die obigen Beiträge - für die ich mich herzlich bedanke - so ansehe, bleibt wohl festzuhalten, dass die Mehrfachvererbung von Schnittstellen beim BCB für die Programmierung vollkommen nutzlos ist und nur insofern einen Vorteil bringt, dass in einem Mehr-Entwicklerprojekt die Koordination verbessert wird, wenn Schnittstellen formal definiert sind und vom Compiler überprüft werden können, oder?
Gruß
Marc