2016-12-09 2 views
3

Ich verwende einige 3rd Party Bibliothek Klassen, die wie folgt definiert sind.Wie kann ich einen Zeiger auf verschiedene Klassen mit gemeinsamen Schnittstellen deklarieren?

class A : public Interface1, public Interface2 {}; 
class B : public Interface1, public Interface2 {}; 

Sie teilen nicht nur eine gemeinsame Basisklasse. Ist es möglich, einen einzelnen Zeigertyp zu deklarieren, der sowohl auf die Klassen A als auch B verweisen kann?

Bitte beachten Sie, dass ich eine 3rd-Party-Bibliothek bin mit und A und B kann nicht neu definieren Wenn ich mich dies tun würde, dann könnte:

class Base : public Interface1, public Interface2 {}; 
class A : public Base {}; 
class B : public Base {}; 

und ich einfach einen Zeiger auf die verwenden könnte dann Basisklasse

Base *pBase; 
+2

Die gemeinsame Basisklasse ist * entweder * 'Interface1' * oder *' Interface2'. Es gibt wirklich keine Möglichkeit, es zu umgehen, wenn Sie den Code nicht umgestalten können. Welchen Sie verwenden sollten, hängt von der Situation und von dem ab, was Sie gerade brauchen. –

+1

Ich schlage nicht vor, es zu benutzen, aber ein 'void *' kann nur irgendetwas referenzieren. Es ist auch möglich, eine "Zeiger" -Klasse zu erstellen, die beide abhängig von ihrem Typ halten kann. – Steeve

Antwort

0

Sie können das nicht direkt tun, wenn Sie den Code nicht umgestalten können.

Das heißt, Sie können immer noch eine Klasse erstellen, die den Typ löscht und immer dann verwendet werden kann, wenn ein Zeiger auf Interface1 oder Interface2 erforderlich ist.
Als Beispiel:

struct S { 
    template<typename T> 
    S(T *t): iface1{t}, iface2{t} {} 

    operator Interface1 *() { return iface1; } 
    operator Interface2 *() { return iface2; } 

private: 
    Interface1 *iface1; 
    Interface2 *iface2; 
}; 

Es hat einen großen Nachteil, mit dem ich weiß nicht, ob Sie umgehen können: ein Zeiger auf S kann nicht auf einen Zeiger auf InterfaceN zugeordnet werden.
Mit anderen Worten:

struct Interface1 {}; 
struct Interface2 {}; 

class A : public Interface1, public Interface2 {}; 
class B : public Interface1, public Interface2 {}; 

struct S { 
    template<typename T> 
    S(T *t): iface1{t}, iface2{t} {} 

    operator Interface1 *() { return iface1; } 
    operator Interface2 *() { return iface2; } 

private: 
    Interface1 *iface1; 
    Interface2 *iface2; 
}; 

int main() { 
    A a; 
    S sa{&a}; 

    // S can be assigned to a pointer to InterfaceN 
    Interface1 *i1ptr = sa; 
    Interface2 *i2ptr = sa; 

    S *sptr = &sa; 

    // sptr cannot be assigned to a pointer 
    // to InterfaceN but you can get one 
    // out of it dereferencing 
    i1ptr = *sptr; 
    i2ptr = *sptr; 
} 

Wenn Sie es akzeptieren können, ist dies eine schmutzige und machbar Abhilfe.


Um ehrlich zu sein, kann ich nicht sehen, warum Sie das tun sollten. Sie könnten einfach Funktionsschablonen erstellen und Zeiger auf A, B und alle anderen Typen weitergeben.
Wie auch immer, ich weiß nicht, was das eigentliche Problem ist, und ich kann nicht aus der Frage herausfinden.
Deshalb hoffe ich, dass es hilft.

Verwandte Themen