Penso che tutte le risposte precedenti abbiano perso di vista la foresta per gli alberi.
I generici Java non sono gli stessi dei template ; usano la cancellazione del tipo , che è una tecnica dinamica , piuttosto che il polimorfismo del tempo di compilazione , che è una tecnica statica . Dovrebbe essere ovvio il motivo per cui queste due tattiche molto diverse non gelano bene.
Anziché tentare di utilizzare un costrutto di compilazione per simulare uno di runtime, diamo un'occhiata a cosa extends
effettivamente fa: secondo Stack Overflow e Wikipedia , extends viene utilizzato per indicare la sottoclasse.
C ++ supporta anche la sottoclasse.
Mostra anche una classe contenitore, che utilizza la cancellazione del tipo sotto forma di un generico, e si estende per eseguire un controllo del tipo. In C ++, devi eseguire tu stesso il tipo di macchina di cancellazione, che è semplice: fai un puntatore alla superclasse.
Inseriamolo in un typedef, per renderlo più facile da usare, piuttosto che creare un'intera classe, et voila:
typedef std::list<superclass*> subclasses_of_superclass_only_list;
Per esempio:
class Shape { };
class Triangle : public Shape { };
typedef std::list<Shape*> only_shapes_list;
only_shapes_list shapes;
shapes.push_back(new Triangle()); // Works, triangle is kind of shape
shapes.push_back(new int(30)); // Error, int's are not shapes
Ora, sembra che List sia un'interfaccia, che rappresenta una sorta di raccolta. Un'interfaccia in C ++ sarebbe semplicemente una classe astratta, cioè una classe che implementa solo metodi virtuali puri. Usando questo metodo, potresti facilmente implementare il tuo esempio java in C ++, senza Concetti o specializzazioni di template. Funzionerebbe anche lentamente come i generici in stile Java a causa delle ricerche nella tabella virtuale, ma questa può spesso essere una perdita accettabile.