Newsgroup: it.comp.lang.c++
Titolo: Interfacce e Template

In Java ho il seguente problema:
public interface Interface
{
   public int methodA();
}
public class BaseA implements Interface
{
   public int methodA() { return 10; }
}
public class BaseB implements Interface
{
   public int methodA() { return 100; }
}
void main(String args[])
{
   ...
   BaseA bA = new BaseA();
   BaseA bB = new BaseB();
   Interface i;
   i = bA;
   anyObject.print(i.methodA());
   i = bB;
   anyObject.print(i.methodA());
   ...
   return;
}
In C++ posso analogamente scrivere
/*
class Interface
{
public:
	virtual int methodA() = 0;
	virtual ~Interface() { }
};
*/
class BaseA // : public virtual Interface
{
public:
	BaseA() { }
	virtual int methodA() { return 10; }
	virtual ~BaseA() { }
};
class BaseB // : public virtual Interface
{
public:
	BaseB() { }
	virtual int methodA() { return 100; }
	virtual ~BaseB() { }
};
/*
template <class PBase>
class Interface
{
	PBase* b;
public:
	Interface(PBase* base): b(base) { }
	inline int methodA() { return b->methodA(); }
	~Interface() { delete b; }
};
*/
template <class PBase>
inline PBase* withInterface(PBase* base)
{ return base; }
int main (int argc, char* argv[])
{
	...
   BaseA* iA = new BaseA();
   BaseB* iB = new BaseB();
   anyObject.print(withInterface(iA)->methodA());
   anyObject.print(withInterface(iB)->methodA());
	...
   delete iA;
   delete iB;
   ...
   return 0;
}
Cioè posso "definire implicitamente" le interfacce tramite una classe
(ed una funzione) template?
Inoltre le dichiarazioni inline sono prese in considerazione dal
compilatore o quest'ultimo in questa situazione non puo considerarle
inline?
Spero di essere stato chiaro. Grazie per i vostri interventi.

 inline?
Il compilatore e' sempre libero di scegliere se espandere in linea o
meno una funzione.
Ciao,
Nicola

 Nicola- Nascondi testo tra virgolette -- Mostra testo tra virgolette -- Nascondi testo tra virgolette -- Mostra testo tra virgolette -

 (cioè la classe Interface)...
Questa e' un'alternativa. L'altra e' quella di usare i template
direttamente:
template <typename ObjectT> void func(ObjectT & o) {
// Qui con "o" puoi fare quello che vuoi indipendentemente dal suo tipo
effettivo, posto di
// chiamare ovviamente solo operazioni presenti in tutti i tipi su cui
chiami func.
}
Ciao,
Nicola


ok, ma se invece ho bisogno di un array di Interface? cioè in Java
Interface list[2] = {new BaseA(), new BaseB()};
for (int i=0; i<2; i++) print(list[i].methodA());
In C++ quindi come faccio a gestire un insieme di "oggetti" Interface?
Quale sarà il tipo dell'array, nell'esempio? Grazie ancora


Il concetto fondamentale e' che se gli oggetti di due classi devono
essere trattati in modo omogeneo a runtime allora devono avere una
classe base comune con le opportune funzioni membro virtuali pure.
Altrimenti si puo' rimanere sui template, ma le cose si complicano
notevolmente. Per esempio puoi usare le tuple, che entreranno a far
parte del prossimo standard:
typedef std::tr1::tuple<BaseA, BaseB> my_tuple;
my_tuple mt(BaseA(), BaseB());
std::cout << mt.get<0>().methodA();
std::cout << mt.get<1>().methodA();
Per scrivere il corrispondente del tuo ciclo e' pero' necessario
servirsi della metaprogrammazione dei template.
Ciao,
Nicola

Giacomino ha scritto:

Interface* list[2] = {new BaseA(), new BaseB()};
for (int i=0; i<2; i++) print(list[i]->methodA());