Utilizzo le pseudointerfacce in C++, ovvero classi astratte pure. Supponiamo che io abbia tre interfacce, IFoo, IBar e IQuux. Ho anche una classe di Fred che implementa tutti e tre:Controllo dell'implementazione dell'interfaccia in fase di compilazione in C++
interface IFoo
{
void foo (void);
}
interface IBar
{
void bar (void);
}
interface IQuux
{
void quux (void);
}
class Fred : implements IFoo, IBar, IQuux
{
}
voglio dichiarare un metodo che accetta qualsiasi oggetto che implementa IFoo e IBar - un Fred avrebbe funzionato, per esempio. L'unico modo di compilazione tempo per fare questo posso immaginare è quello di definire una terza IFooAndBar interfaccia che implementa entrambi, e ridichiarare Fred:
interface IFooAndBar : extends IFoo, IBar
{
}
class Fred : implements IFooAndBar, IQuux
{
}
ora posso dichiarare il mio metodo come la ricezione di un IFooAndBar *. Fin qui tutto bene.
Tuttavia, che cosa succede se voglio anche un metodo diverso che accetta IBar e IQuux? Ho provato dichiara una nuova interfaccia IBarAndQuux e dichiarando Fred come ereditare entrambi:
class IFooAndBar : IFoo, IBar
{
};
class IBarAndQuux : IBar, IQuux
{
};
class Fred : IFooAndBar, IBarAndQuux
{
};
Questo funziona quando passo Fred come IFooAndBar ad un metodo; tuttavia, quando provo a chiamare Fred :: bar() direttamente, gcc si lamenta:
error: request for member ‘bar’ is ambiguous
error: candidates are: void IBar::bar()
error: void IBar::bar()
che rende questa soluzione più o meno inutile.
Il mio prossimo tentativo è stato quello di dichiarare Fred come eredita da tre singole interfacce, e rendendo il metodo accetta una delle interfacce ibride come parametro:
class Fred : public IFoo, public IBar, public IBaz
{
};
void doTest (IBarAndBaz* pObj)
{
pObj->bar();
pObj->baz();
}
Quando provo a passare Fred come IBarAndBaz * parametro, ottengo un errore, come previsto:
error: cannot convert ‘Fred*’ to ‘IBarAndBaz*’ for argument ‘1’ to ‘void doTest(IBarAndBaz*)’
dynamic_cast <> anche p roduces un errore (che non capisco)
error: cannot dynamic_cast ‘pFred’ (of type ‘class Fred*’) to type ‘class IBarAndBaz*’ (source type is not polymorphic)
Forzare un cast fa lavoro, tuttavia:
doTest((IBarAndBaz*)pFred);
ma mi chiedo come sicuro e portatile questo è (I sviluppare per Linux, Mac e Windows) e se funziona in una situazione reale.
Infine, mi rendo conto mio metodo può accettare un puntatore a una delle interfacce e dynamic_cast per l'altro (s) per far rispettare il tipo di parametro corretto in fase di esecuzione, ma preferisco una soluzione in fase di compilazione.
Non è sicuro e non è portatile. In effetti, non è definito in C++. –