H
Hallo,
1. ist das
virtual bool IDirectGraphic::setMode (int value)
{ std::cout << "Interface IDirectGraphic wird benutzt!" << std::endl; return true; }
virtual bool IDirectGraphic2::setMode (int value)
{ std::cout << "Interface IDirectGraphic2 wird benutzt!" << std::endl; return true; }
mal kein Standard-C++. Die qualifizierten Namen IDirectGraphic::setMode bzw. IDirectGraphic2::setMode sind im Class-Scope nicht erlaubt. Nur im Namespace-Scope.
Zu deinem Problem:
Wenn ich dich richtig verstehe, ist das deine Situation (COM-befreit):
class A
{
public:
virtual void func();
};
class B
{
public:
virtual void func();
};
class C : public A, public B
{
public:
void func();
};
Du hast also zwei Klassen A und B die jeweils eine virtuelle Funktion mit dem *selben* Namen definieren und eine Klasse C, die von A und B erbt und die virtuelle Funktion überschreiben soll.
Gleichzeitig soll die Funktionalität der virtuellen Funktion aber abhängig vom Interface sein. Sprich:
C c;
A* pA = &c;
pA->func(); // soll A::func aufrufen
B* pB = &c;
pB->func(); // soll B::func aufrufen
c.func(); // soll C::func aufrufen
Die schlechte Nachricht: Das geht nicht. C::func überschreibt *beide* virtuellen Funktionen, wird hier also immer aufgerufen. Du hast danach *keine* Möglichkeit mehr, die beiden zu unterscheiden. Sprich: Du kannst in C::func *nicht* herausfinden, ob du über ein A-Interfac, B-Interface oder C-Interface aufgerufen wurdest.
Es gibt jetzt zwei mögliche Lösungen:
1. Wenn du func nicht über C aufrufen musst und du kein spezielles Verhalten in der am weitesten abgeleiteten Klasse brauchst, dann kannst du einfach auf das Überschreiben in C verzichten. Der Aufruf ist dann nur noch über das A-Interface oder das B-Interface möglich:
int main()
{
C c;
A* pA = &c; // OK: A::func
pA->func();
B* pB = &c;
pB->func(); // OK: B::fun
c.func(); // FEHLER! Mehrdeutig
}
2. Falls du wirklich eine Überschreibung in C brauchst, bleibt dir nichts anderes übrig, als die "Siamesichen Zwillinge" zu trennen.
Das Problem ist klar: Zwei Funktionen haben den gleichen Namen. Lösung: Ändere den Namen. Und zwar per Vererbung.
Zur Klasse A baust du eine abgeleitet Klasse AI, die der virtuellen Funktion einen neuen Namen gibt und zur alten Funktion forwarded:
class AI : public A
{
public:
virtual void Afunc() = 0;
private:
void func() // überschreibt A::Func...
{
Afunc(); // und forwarded zu unserer neuen Funktion
}
};
Für B genauso:
class BI : public B
{
public:
virtual void Bfunc() = 0;
private:
void func() // überschreibt B::Func...
{
Bfunc(); // und forwarded zu unserer neuen Funktion
}
};
C erbt nun statt von A und B von AI und BI. Hier überschreibst du nicht mehr func sondern Afunc und Bfunc:
class C : public AI, public BI
{
public:
void Afunc()
{
cout << "C als A" << endl;
}
void Bfunc()
{
cout << "C als B" << endl;
}
};
In eine cpp-Datei packst du das natürlich wie gewohnt:
// c.h
class C : public AI, public BI
{
public:
void Afunc();
void Bfunc();
};
// c.cpp
void C::Afunc() {...}
void C::Bfunc() {...}
PS:: Sollten A oder B viele und komplizierte Konstruktoren besitzen, dann bietet es sich an AI und BI jeweils virtuell erben zu lassen. Damit ersparst du dir die Duplizierung des Ctor-Codes in AI bzw. BI.