2017-05-24 1 views
-1

J'ai une classe abstraite Primitive, qui a quelques fonctions abstraites pures.Comment créer une instanciation de modèle pour un baseclass abstrait?

Puis-je avoir une mise en œuvre de l'arbre avec des modèles:

template<typename PrimitiveT> 
class PrimitiveTree { 
    ... 
} 
// explicit instantiation 
template class PrimitiveTree<Project::Primitive>; // abstract 
template class PrimitiveTree<SimpleTrianglePrimitive>; // implementation 

qui est utilisé dans un autre fichier comme

PrimitiveTree<Primitive> *ptree; 

Avec ce code, je reçois error C2259: 'Project::Primitive': cannot instantiate abstract class. Lorsque je supprime l'instanciation de la classe abstraite, j'obtiens des erreurs de liens que le symbole correspondant pour PrimitiveTree<Primitive> n'est pas trouvé dans le fichier objet.

Une classe similaire avec les méthodes dans le fichier d'en-tête n'a pas ces problèmes, lorsqu'il est utilisé avec Primitive comme argument de modèle.

Comment ai-je besoin d'instancier la classe de modèle, de sorte que les symboles neccessary sont ajoutés au fichier objet, même si l'argument de modèle est une classe abstraite?

+1

En général, il est une mauvaise idée de mélanger polymorphisme dynamique avec des modèles. Réfléchissez deux fois – KonstantinL

+1

Veuillez fournir un [MVCE] (https://stackoverflow.com/help/mcve). Il n'est pas clair comment le paramètre de modèle 'PrimitiveT' est utilisé par les (spécialisations du) modèle de classe' PrimitiveTree'. – Walter

+0

@Walter il y a une balise magique '[mcve]' pour [mcve] –

Répondre

1

Vous devez vous assurer que le modèle PrimitiveTree<PrimitiveT> ne dépend pas de PrimitiveT (le paramètre modèle) étant instanciable - en d'autres termes, n'étant pas abstrait. Une propriété d'une classe abstraite est qu'elle ne peut pas être instanciée.

Cela signifie que votre modèle PrimitiveTree doit uniquement fonctionner avec des pointeurs ou des références à PrimitiveT, et ne jamais instancier une instance réelle PrimitiveT de quelque manière que ce soit. Cela signifie qu'il n'est pas possible de déclarer PrimitiveT en tant que membre de données (statique ou non statique). Il n'est pas possible de transmettre un PrimitiveT en valeur. Il est également impossible de créer dynamiquement des instances avec une expression new (par exemple some_pointer = new PrimitiveT[5]) car une expression new repose sur le type étant instanciable (à savoir non abstraite).

Partout où PrimitiveT est utilisé doit être une référence ou un pointeur. La définition ou la déclaration d'un pointeur ou d'une référence à PrimitiveT, ou le passage d'une référence/d'un pointeur en tant qu'argument de la fonction ne dépend pas de l'instabilité de PrimitiveT.

Si vous écrivez un code ANY pour PrimitiveTree qui repose sur PrimitiveT étant instancié, l'implémentation ne peut pas instancier le modèle. La "classe similaire" dans un autre fichier d'en-tête ne dépend probablement pas de Primitive étant instanciable, car il suit les directives comme ci-dessus.

+0

Cela a résolu le problème. – allo