J'ai une quantité finie de classes avec la même implémentation, le seul différent étant le type de données sous-jacent qu'ils manipulent: J'aimerais réduire la duplication de code de Ces classes en utilisant des modèles comme: p> et spécialisation: p> Cela fonctionne bien. mais strong> J'aimerais également ajouter une classe de base abstrait à ces classes spécialisées pour pouvoir les manipuler de manière générique (par exemple, dans une collection). Le problème est que cette classe de base doit avoir le Je voudrais le mettre en œuvre avec quelque chose comme ceci: p> et l'utiliser comme ça: p> getdata code> et
setdata code> pour pouvoir les appeler même sans connaître le type dynamique de l'objet manipulé. P>
int main(int argc, char const *argv[])
{
IntContainer intc = IntContainer();
intc.setData(42);
std::cout << intc.getData() << std::endl;
BoolContainer boolc = BoolContainer();
boolc.setData(false);
std::cout << boolc.getData() << std::endl;
std::vector<Base> v;
v.push_back(intf);
v.push_back(boolf);
for (std::vector<Base>::iterator it = v.begin() ; it != v.end(); ++it)
std::cout << it->getData() << std::endl;
return 0;
}
4 Réponses :
Il n'y a tout simplement aucun moyen de faire ce que vous voulez. P>
Le problème est que, si cela a été autorisé, le compilateur devrait générer autant de méthodes virtuelles dans la classe de base, car il existe des spécialisations possibles de la classe enfant de modèle (c'est-à-dire une infini) qui n'est pas possible. P >
D'accord - Ce que vous voulez, c'est une langue dactylographiée dynamiquement, que c ++ n'est pas.
Sachant que je n'ai besoin que d'une quantité finie de classes dérivées (je ne veux pas de «généricité complète», seulement du code sec), connaissez-vous un moyen de contourner mon problème?
Du faire de la fabrication de modèle de base aussi? Bien sûr, il n'y a aucun moyen de faire quelque chose comme mais le reste que vous pouvez réaliser avec quelque chose de simple comme p> vous pouvez utiliser de quelque manière que ce soit aussi longtemps que les types correspondent. P> IntContainer intc = IntContainer();
intc.setData(42);
std::cout << intc.getData() << std::endl;
BoolContainer boolc = BoolContainer();
boolc.setData(true);
std::cout << boolc.getData() << std::endl;
std::vector<IntContainer> v;
v.push_back(intc);
// v.push_back(boolc); No can't do.
Il s'agit d'une solution pour tout type de classes pouvant aller-t'aller via un avec moins de types, vous pouvez faire quelque chose de similaire, tant que vous avez des fonctions de conversion entre eux. P> Alternativement, si vous comme des exceptions, vous pouvez lancer. p> Alternativement, vous pouvez utiliser stringstream code>, et une telle conversion est la bonne façon de convertir entre les types. Ce n'est pas efficace du tout:
boost :: variante code> S, qui ne font aucune conversion, mais fonctionne à partir d'une liste finie de types (ils sont fondamentalement étiquetés.
Union code> S qui prend en charge plus de types que c ++ 03 laisse
Union code> et avec une belle sémantique sur Attribuer / copier / etc.). P> P>
En supposant que vous avez une certaine flexibilité de conception, vous pouvez modifier votre interface pour accueillir cela, bien que ce n'est pas aussi efficace qu'une table virtuelle infinie
Vous pouvez définir des valeurs via la construction, ou Vous pouvez obtenir des valeurs via Votre Notez que les copies sont plus efficaces si le compilateur sait qu'il copie d'un générique à un autre par opposition à la base à la base p> >> code> < / p>
<<< / code> p>
vecteur code> doit être un pointeur de base ou une référence, la taille de chaque base L'objet est variable, le pointeur, explicite ou implicite à travers une référence est d'une taille code> fixe p>
Qu'espérez-vous pouvoir faire en ajoutant cette classe de base? La connaissance de cela façonnerait fortement des réponses potentielles.
Fondamentalement, j'espérais avoir un ensemble de méthodes de cours dérivées fortement typées (c.-à-d. Ne pouvoir appeler
setingdata (int Data) code> sur un
boolcontainer code>) mais avec la capacité Itérer sur une collection de ces classes (probablement un
std :: vecteur code>).
... Mais peut-être que je pense trop avec un objectif objectif de ces jours-ci.
Je pense que le mauvais tour était de choisir le polymorphisme de la compilée (modèles) lorsque vous souhaitez retarder ce comportement jusqu'au temps d'exécution (collections arbitraires de ces objets)