web-dev-qa-db-fra.com

Comment gérez-vous une erreur "Impossible d'instancier une classe abstraite" en C ++?

Comment gérez-vous une erreur "Impossible d'instancier une classe abstraite" en C++? J'ai examiné certaines des erreurs similaires ici et aucune d'entre elles ne semble être exactement la même ou le problème que j'ai. Mais, encore une fois, je dois admettre qu'il y en a plusieurs à parcourir. Voici l'erreur de compilation:

[IMG]http://i67.photobucket.com/albums/h292/Athono/cannotinstantiateabstractclass.png[/IMG]

Cela m'amène à cette page: http://msdn.Microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k (C2259); k (VS.ERRORLIST) & rd = true L'erreur de compilation C2259 provient d'un programme C++ mais la page appelle la classe abstraite une "interface":

Chaque fois que vous dérivez d'une interface et implémentez les méthodes d'interface dans la classe dérivée avec des autorisations d'accès autres que publiques, vous pouvez recevoir C2259. Cela se produit car le compilateur attend que les méthodes d'interface implémentées dans la classe dérivée aient un accès public. Lorsque vous implémentez les fonctions membres pour une interface avec des autorisations d'accès plus restrictives, le compilateur ne les considère pas comme des implémentations pour les méthodes d'interface définies dans l'interface, ce qui à son tour fait de la classe dérivée une classe abstraite.

Il existe deux solutions de contournement possibles pour le problème:

Rendez les autorisations d'accès publiques pour les méthodes implémentées.

Utilisez l'opérateur de résolution de portée pour les méthodes d'interface implémentées dans la classe dérivée pour qualifier le nom de méthode implémenté avec le nom de l'interface.

La mauvaise nouvelle est que j'ai déjà rendu toutes les méthodes publiques dans la classe:

class AmbientOccluder: public Light {
    public:

        AmbientOccluder(void); 
17
xarzu

L'erreur signifie que certaines méthodes de la classe ne sont pas implémentées. Vous ne pouvez pas instancier une telle classe, donc il n'y a rien que vous puissiez faire, à part implémenter toutes les méthodes de la classe.

D'un autre côté, un modèle courant consiste à instancier une classe concrète et à l'affecter à un pointeur d'une classe de base abstraite:

class Abstract { /* stuff */ 4};
class Derived : virtual public Abstract { /* implement Abstract's methods */ };

Abstract* pAbs = new Derived; // OK

Juste un côté, pour éviter les problèmes de gestion de la mémoire avec la ligne ci-dessus, vous pouvez envisager d'utiliser un pointeur intelligent , comme un `std :: unique_ptr:

std::unique_ptr<Abstract> pAbs(new Derived);
33
juanchopanza

Visual Studio Liste d'erreurs volet affiche uniquement la première ligne de l'erreur. Appelez View> Output et je parie que vous verrez quelque chose comme:

c:\path\to\your\code.cpp(42): error C2259: 'AmbientOccluder' : cannot instantiate abstract class
          due to following members:
          'ULONG MysteryUnimplementedMethod(void)' : is abstract
          c:\path\to\some\include.h(8) : see declaration of 'MysteryUnimplementedMethod'
25
Olivier Dagenais

Une classe abstraite ne peut pas être instanciée par définition. Pour utiliser cette classe, vous devez créer une sous-classe concrète qui implémente toutes les fonctions virtuelles de la classe. Dans ce cas, vous n'avez probablement pas implémenté toutes les fonctions virtuelles déclarées dans Light. Cela signifie que AmbientOccluder par défaut est une classe abstraite. Pour que nous puissions vous aider davantage, vous devez inclure les détails de la classe Light.

9
Code-Apprentice

Fournissez une implémentation pour toutes les fonctions virtuelles pures de la classe.

3
bazz

Pourquoi ne pouvons-nous pas créer un objet de classe abstraite? Lorsque nous créons une fonction virtuelle pure dans la classe Abstract, nous réservons un emplacement pour une fonction dans la VTABLE (étudié dans le dernier sujet), mais ne met aucune adresse dans cet emplacement. Par conséquent, la VTABLE sera incomplète. Comme la classe VTABLE for Abstract est incomplète, le compilateur ne permettra pas la création d'objet pour une telle classe et affichera un message d'erreur chaque fois que vous tenterez de le faire.

Définitions virtuelles pures

Les fonctions Pure Virtual peuvent recevoir une petite définition dans la classe Abstract, que vous voulez que toutes les classes dérivées aient. Vous ne pouvez toujours pas créer d'objet de classe Abstract. De plus, la fonction Pure Virtual doit être définie en dehors de la définition de classe. Si vous le définissez dans la définition de classe, complier donnera une erreur. La définition virtuelle pure en ligne est illégale.

1
vaibhav gupta

Dans mon cas, j'ai déclaré une fonction dans COM Control .idl fichier comme

[id(1)] HRESULT MyMethod([in]INT param);

mais pas déclaré dans mon interface .h fichier comme celui-ci

STDMETHOD(MyMethod)(INT param);

Problème résolu en ajoutant la ligne ci-dessus dans mon fichier d'interface .h

cela pourrait aider quelqu'un.

0
CLIFFORD P Y

J'ai répondu à cette question ici .. Problème de type de retour des fonctions virtuelles covariantes

Voyez si cela aide quelqu'un.

0