Lors de la construction de mon programme C ++, je reçois le message d'erreur
référence non définie à «vtable ...
Quelle est la cause de ce problème? Comment je le répare?
Il se trouve que j'obtiens l'erreur pour le code suivant (la classe en question est CGameModule.) Et je ne peux pas pour la vie de moi comprendre quel est le problème. Au début, je pensais que c'était lié à l'oubli de donner un corps à une fonction virtuelle, mais d'après ce que je comprends, tout est là. La chaîne d'héritage est un peu longue, mais voici le code source associé. Je ne sais pas quelles autres informations je dois fournir.
Remarque: Le constructeur est l'endroit où cette erreur se produit, semble-t-il.
Mon code:
class CGameModule : public CDasherModule {
public:
CGameModule(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, const char *szName)
: CDasherModule(pEventHandler, pSettingsStore, iID, 0, szName)
{
g_pLogger->Log("Inside game module constructor");
m_pInterface = pInterface;
}
virtual ~CGameModule() {};
std::string GetTypedTarget();
std::string GetUntypedTarget();
bool DecorateView(CDasherView *pView) {
//g_pLogger->Log("Decorating the view");
return false;
}
void SetDasherModel(CDasherModel *pModel) { m_pModel = pModel; }
virtual void HandleEvent(Dasher::CEvent *pEvent);
private:
CDasherNode *pLastTypedNode;
CDasherNode *pNextTargetNode;
std::string m_sTargetString;
size_t m_stCurrentStringPos;
CDasherModel *m_pModel;
CDasherInterfaceBase *m_pInterface;
};
Hérite de ...
class CDasherModule;
typedef std::vector<CDasherModule*>::size_type ModuleID_t;
/// \ingroup Core
/// @{
class CDasherModule : public Dasher::CDasherComponent {
public:
CDasherModule(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, ModuleID_t iID, int iType, const char *szName);
virtual ModuleID_t GetID();
virtual void SetID(ModuleID_t);
virtual int GetType();
virtual const char *GetName();
virtual bool GetSettings(SModuleSettings **pSettings, int *iCount) {
return false;
};
private:
ModuleID_t m_iID;
int m_iType;
const char *m_szName;
};
Qui hérite de ....
namespace Dasher {
class CEvent;
class CEventHandler;
class CDasherComponent;
};
/// \ingroup Core
/// @{
class Dasher::CDasherComponent {
public:
CDasherComponent(Dasher::CEventHandler* pEventHandler, CSettingsStore* pSettingsStore);
virtual ~CDasherComponent();
void InsertEvent(Dasher::CEvent * pEvent);
virtual void HandleEvent(Dasher::CEvent * pEvent) {};
bool GetBoolParameter(int iParameter) const;
void SetBoolParameter(int iParameter, bool bValue) const;
long GetLongParameter(int iParameter) const;
void SetLongParameter(int iParameter, long lValue) const;
std::string GetStringParameter(int iParameter) const;
void SetStringParameter(int iParameter, const std::string & sValue) const;
ParameterType GetParameterType(int iParameter) const;
std::string GetParameterName(int iParameter) const;
protected:
Dasher::CEventHandler *m_pEventHandler;
CSettingsStore *m_pSettingsStore;
};
/// @}
#endif
qmake -project
, puisqmake
) pour générer un nouveauMakefile
, c'est probablement une source d'erreur lors de l'utilisation de Qt.Q_OBJECT
est copié en externe, mais ne fait pas encore partie du fichier .pro, bien qu'il compile bien, il ne se lie pas. Nous devons ajouter ce.h/.cpp
fichier dans le fichier .pro pour pouvoirqmake
.Réponses:
La FAQ du CCG contient une entrée:
la source
nm -C CGameModule.o | grep CGameModule::
répertorie les méthodes définies, en supposant que l'intégralité de votre implémentation de classe va dans le fichier d'objet logique. Vous pouvez comparer cela avec ce qui est défini comme virtuel pour comprendre ce que vous avez manqué.Pour ce que ça vaut, oublier un corps sur un destructeur virtuel génère ce qui suit:
J'ajoute une note car le message d'erreur est trompeur. (C'était avec la version 4.6.3 de gcc.)
la source
~Destructor = default;
dans le fichier d'en-tête n'a pas aidé. Existe-t-il un bogue documenté contre gcc?Donc, j'ai compris le problème et c'était une combinaison de mauvaise logique et de ne pas être totalement familier avec le monde automake / autotools. J'ajoutais les fichiers corrects à mon modèle Makefile.am, mais je ne savais pas quelle étape de notre processus de création avait réellement créé le makefile lui-même. Donc, je compilais avec un vieux makefile qui n'avait aucune idée de mes nouveaux fichiers.
Merci pour les réponses et le lien vers la FAQ GCC. Je serai sûr de lire cela pour éviter que ce problème ne se produise pour une vraie raison.
la source
Si vous utilisez Qt, essayez de relancer qmake. Si cette erreur se trouve dans la classe du widget, qmake peut ne pas avoir remarqué que la table ui de classe doit être régénérée. Cela a résolu le problème pour moi.
la source
qmake
, j'ai eu la même chose aveccmake
. Une partie du problème pourrait être que les deux outils ont un peu un problème avec les fichiers d'en-tête, qui ne déclenchent pas toujours une reconstruction en cas de besoin.Une référence non définie à vtable peut également se produire en raison de la situation suivante. Essayez ceci:
La classe A contient:
La classe B contient:
La classe C contient: Maintenant, vous écrivez une classe C dans laquelle vous allez la dériver de la classe A.
Maintenant, si vous essayez de compiler, vous obtiendrez une référence indéfinie à vtable pour la classe C en tant qu'erreur.
Raison:
functionA
est défini comme virtuel pur et sa définition est fournie dans la classe B.functionB
est défini comme virtuel (PAS PURE VIRTUEL), il essaie donc de trouver sa définition dans la classe A elle-même, mais vous avez fourni sa définition dans la classe B.Solution:
virtual void functionB(parameters) =0;
(cela fonctionne, il est testé)la source
J'ai simplement eu cette erreur car mon fichier cpp n'était pas dans le makefile.
la source
undefined reference to {function/class/struct}
quand il y a desvirtual
choses impliquées. Me jeta.Qu'est-ce qu'un
vtable
?Il peut être utile de savoir de quoi parle le message d'erreur avant d'essayer de le corriger. Je vais commencer à un niveau élevé, puis je descendrai jusqu'à plus de détails. De cette façon, les gens peuvent avancer une fois qu'ils sont à l'aise avec leur compréhension des vtables. … Et il y a un tas de gens qui sautent en ce moment. :) Pour ceux qui restent:
Une vtable est fondamentalement l'implémentation la plus courante du polymorphisme en C ++ . Lorsque vtables est utilisé, chaque classe polymorphe a une vtable quelque part dans le programme; vous pouvez le considérer comme un
static
membre de données (caché) de la classe. Chaque objet d'une classe polymorphe est associé à la table virtuelle pour sa classe la plus dérivée. En vérifiant cette association, le programme peut travailler sa magie polymorphe. Mise en garde importante: une table virtuelle est un détail d'implémentation. Il n'est pas mandaté par la norme C ++, même si la plupart (tous?) Des compilateurs C ++ utilisent vtables pour implémenter un comportement polymorphe. Les détails que je présente sont des approches typiques ou raisonnables. Les compilateurs sont autorisés à s'en écarter!Chaque objet polymorphe a un pointeur (caché) vers la table virtuelle pour la classe la plus dérivée de l'objet (éventuellement plusieurs pointeurs, dans les cas les plus complexes). En regardant le pointeur, le programme peut dire quel est le type "réel" d'un objet (sauf pendant la construction, mais sautons ce cas spécial). Par exemple, si un objet de type
A
ne pointe pas vers la table deA
, cet objet est en fait un sous-objet de quelque chose dérivé deA
.Le nom "vtable" vient de " v irtual function table ". Il s'agit d'un tableau qui stocke des pointeurs vers des fonctions (virtuelles). Un compilateur choisit sa convention pour la présentation de la table; une approche simple consiste à parcourir les fonctions virtuelles dans l'ordre dans lequel elles sont déclarées dans les définitions de classe. Lorsqu'une fonction virtuelle est appelée, le programme suit le pointeur de l'objet vers une table virtuelle, accède à l'entrée associée à la fonction souhaitée, puis utilise le pointeur de fonction stocké pour appeler la fonction correcte. Il y a plusieurs astuces pour faire fonctionner cela, mais je ne vais pas entrer dans celles-ci ici.
Où / quand est
vtable
généré?Une table virtuelle est générée automatiquement (parfois appelée "émise") par le compilateur. Un compilateur pourrait émettre une vtable dans chaque unité de traduction qui voit une définition de classe polymorphe, mais cela serait généralement inutile. Une alternative ( utilisée par gcc , et probablement par d'autres) consiste à choisir une seule unité de traduction dans laquelle placer la table virtuelle, de la même manière que vous choisiriez un seul fichier source dans lequel placer les membres de données statiques d'une classe. Si ce processus de sélection ne parvient pas à sélectionner des unités de traduction, la table virtuelle devient une référence non définie. D'où l'erreur, dont le message n'est certes pas particulièrement clair.
De même, si le processus de sélection choisit une unité de traduction, mais que ce fichier objet n'est pas fourni à l'éditeur de liens, alors la table virtuelle devient une référence non définie. Malheureusement, le message d'erreur peut être encore moins clair dans ce cas que dans le cas où le processus de sélection a échoué. (Merci aux répondeurs qui ont mentionné cette possibilité. Je l'aurais probablement oubliée autrement.)
Le processus de sélection utilisé par gcc prend tout son sens si nous partons de la tradition de consacrer un (seul) fichier source à chaque classe qui en a besoin pour sa mise en œuvre. Ce serait bien d'émettre la vtable lors de la compilation de ce fichier source. Appelons cela notre objectif. Cependant, le processus de sélection doit fonctionner même si cette tradition n'est pas respectée. Ainsi, au lieu de rechercher l'implémentation de la classe entière, recherchons l'implémentation d'un membre spécifique de la classe. Si la tradition est respectée - et si ce membre est en fait mis en œuvre - alors cela atteint l'objectif.
Le membre sélectionné par gcc (et potentiellement par d'autres compilateurs) est la première fonction virtuelle non en ligne qui n'est pas pure virtuelle. Si vous faites partie de la foule qui déclare les constructeurs et les destructeurs avant les autres fonctions membres, alors ce destructeur a de bonnes chances d'être sélectionné. (Vous vous souveniez de rendre le destructeur virtuel, non?) Il y a des exceptions; Je m'attends à ce que les exceptions les plus courantes soient lorsqu'une définition en ligne est fournie pour le destructeur et lorsque le destructeur par défaut est demandé (en utilisant "
= default
").L'astucieux pourrait remarquer qu'une classe polymorphe est autorisée à fournir des définitions en ligne pour toutes ses fonctions virtuelles. Cela ne fait-il pas échouer le processus de sélection? C'est le cas dans les anciens compilateurs. J'ai lu que les derniers compilateurs ont résolu cette situation, mais je ne connais pas les numéros de version pertinents. Je pourrais essayer de chercher cela, mais il est plus facile de coder autour ou d'attendre que le compilateur se plaint.
En résumé, il existe trois causes principales de l'erreur "référence non définie à vtable":
Ces causes sont en elles-mêmes insuffisantes pour provoquer l'erreur par elles-mêmes. Voici plutôt ce à quoi vous vous adresseriez pour résoudre l'erreur. Ne vous attendez pas à ce que la création intentionnelle d'une de ces situations produise définitivement cette erreur; il y a d'autres exigences. Attendez-vous à ce que la résolution de ces situations résout cette erreur.
(OK, le numéro 3 aurait peut-être suffi lorsque cette question a été posée.)
Comment corriger l'erreur?
Bienvenue aux gens qui sautent! :)
= 0
") et dont vous définissez la définition (pas "= default
").Exemple
Les détails de la procédure à suivre peuvent varier et parfois se diviser en questions distinctes (comme Qu'est-ce qu'une erreur de référence externe non définie / symbole non résolu et comment puis-je la corriger? ). Je vais cependant fournir un exemple de ce qu'il faut faire dans un cas spécifique qui pourrait dérouter les nouveaux programmeurs.
L'étape 1 mentionne la modification de votre classe afin qu'elle ait une fonction d'un certain type. Si la description de cette fonction vous dépasse, vous pourriez être dans la situation que j'ai l'intention de résoudre. Gardez à l'esprit que c'est une façon d'atteindre l'objectif; ce n'est pas le seul moyen, et il pourrait facilement y avoir de meilleurs moyens dans votre situation spécifique. Appelons votre classe
A
. Votre destructeur est-il déclaré (dans votre définition de classe) commeou
? Si c'est le cas, deux étapes changeront votre destructeur en le type de fonction que nous voulons. Tout d'abord, changez cette ligne en
Ensuite, mettez la ligne suivante dans un fichier source qui fait partie de votre projet (de préférence le fichier avec l'implémentation de classe, si vous en avez un):
Cela rend votre destructeur (virtuel) non en ligne et non généré par le compilateur. (N'hésitez pas à modifier les choses pour mieux correspondre à votre style de mise en forme de code, par exemple en ajoutant un commentaire d'en-tête à la définition de la fonction.)
la source
Il y a beaucoup de spéculations dans diverses réponses ici. Je vais donner ci-dessous un code assez minimal qui reproduit cette erreur et expliquer pourquoi elle se produit.
Code assez minimal pour reproduire cette erreur
IBase.hpp
Derived.hpp
Derived.cpp
myclass.cpp
Vous pouvez compiler cela en utilisant GCC comme ceci:
Vous pouvez maintenant reproduire l'erreur en supprimant
= 0
dans IBase.hpp. Je reçois cette erreur:Explication
Notez que le code ci-dessus ne nécessite aucun destructeur, constructeur ou autre fichier supplémentaire pour que la compilation réussisse (bien que vous devriez les avoir).
La façon de comprendre cette erreur est la suivante: Linker recherche le constructeur d'IBase. Il en aura besoin pour le constructeur de Derived. Cependant, étant donné que Derived remplace les méthodes d'IBase, il est associé à vtable qui fera référence à IBase. Lorsque l'éditeur de liens dit "référence non définie à vtable pour IBase", cela signifie essentiellement que Derived a une référence vtable à IBase mais qu'il ne peut trouver aucun code objet compilé d'IBase à rechercher. Donc, l'essentiel est que la classe IBase a des déclarations sans implémentations. Cela signifie qu'une méthode dans IBase est déclarée virtuelle mais nous avons oublié de la marquer comme virtuelle pure OU de fournir sa définition.
Conseil de séparation
Si tout le reste échoue, une façon de déboguer cette erreur est de créer un programme minimal qui compile et de continuer à le modifier pour qu'il atteigne l'état souhaité. Entre les deux, continuez à compiler pour voir quand il commence à échouer.
Remarque sur ROS et Catkin build system
Si vous compiliez l'ensemble de classes ci-dessus dans ROS en utilisant le système de construction catkin, vous aurez besoin des lignes suivantes dans CMakeLists.txt:
La première ligne dit essentiellement que nous voulons créer un exécutable nommé myclass et le code pour le construire peut être trouvé dans les fichiers qui suivent. L'un de ces fichiers devrait avoir main (). Notez que vous n'avez pas besoin de spécifier les fichiers .hpp n'importe où dans CMakeLists.txt. Vous n'avez pas non plus à spécifier Derived.cpp comme bibliothèque.
la source
Je viens de rencontrer une autre cause de cette erreur que vous pouvez rechercher.
La classe de base a défini une fonction virtuelle pure comme:
Et la sous-classe avait
Le problème était la faute de frappe qui
"=0"
devait être en dehors de la parenthèse:Donc, si vous faites défiler aussi loin, vous n'avez probablement pas trouvé la réponse - c'est autre chose à vérifier.
la source
Cela peut se produire assez facilement si vous oubliez de créer un lien vers le fichier objet qui a la définition.
la source
Le compilateur GNU C ++ doit décider où mettre le
vtable
cas où vous avez la définition des fonctions virtuelles d'un objet réparties sur plusieurs unités de compilation (par exemple, certaines des définitions des fonctions virtuelles des objets se trouvent dans un fichier .cpp, d'autres dans un autre. fichier cpp, etc.).Le compilateur choisit de mettre le
vtable
au même endroit que celui où la première fonction virtuelle déclarée est définie.Maintenant, si pour une raison quelconque, vous avez oublié de fournir une définition pour cette première fonction virtuelle déclarée dans l'objet (ou si vous avez oublié par erreur d'ajouter l'objet compilé à la phase de liaison), vous obtiendrez cette erreur.
En tant qu'effet secondaire, veuillez noter que ce n'est que pour cette fonction virtuelle particulière que vous n'obtiendrez pas l'erreur de l'éditeur de liens traditionnel, car il vous manque la fonction foo .
la source
Pas pour traverser le poteau mais. Si vous avez affaire à un héritage le deuxième succès de Google était ce que j'avais manqué, c'est-à-dire. toutes les méthodes virtuelles doivent être définies.
Tel que:
Voir answare C ++ Undefined Reference to vtable and inheritance pour plus de détails. Je viens de réaliser que c'est déjà mentionné ci-dessus, mais diable cela pourrait aider quelqu'un.
la source
Ok, la solution à cela est que vous avez peut-être manqué la définition. Voir l'exemple ci-dessous pour éviter l'erreur du compilateur vtable:
la source
CDasherComponent
a un corps pour le destructeur? Ce n'est certainement pas ici - la question est de savoir s'il se trouve dans le fichier .cc.CDasherModule
devrait définir explicitement son destructeurvirtual
.CGameModule
avoir un extra}
à la fin (après la}; // for the class
).CGameModule
ce lié aux bibliothèques qui définissentCDasherModule
etCDasherComponent
?la source
Peut-être que manquer le destructeur virtuel est un facteur contributif?
la source
Ce fut le premier résultat de recherche pour moi, donc j'ai pensé ajouter une autre chose à vérifier: assurez-vous que la définition des fonctions virtuelles est bien dans la classe. Dans mon cas, j'avais ceci:
En tête de fichier:
et dans mon fichier .cc:
Cela devrait lire
la source
Pas peut-être. Manque définitivement
~CDasherModule() {}
.la source
Tant de réponses ici, mais aucune ne semblait avoir couvert mon problème. J'avais ce qui suit:
Et dans un autre fichier (inclus dans la compilation et la liaison, bien sûr)
Eh bien, cela n'a pas fonctionné et j'ai eu l'erreur dont tout le monde parle. Pour le résoudre, j'ai dû déplacer la définition réelle de Foo hors de la déclaration de classe en tant que telle:
Je ne suis pas un gourou du C ++ donc je ne peux pas expliquer pourquoi c'est plus correct mais cela a résolu le problème pour moi.
la source
J'utilisais donc Qt avec Windows XP et le compilateur MinGW et cette chose me rendait fou.
Fondamentalement, le moc_xxx.cpp a été généré vide même lorsque j'ai été ajouté
Q_OBJECT
Supprimer tout ce qui rend les fonctions virtuelles, explicites et tout ce que vous pensez ne fonctionne pas. Enfin, j'ai commencé à supprimer ligne par ligne et il s'est avéré que j'avais
Autour du fichier. Même lorsque #ifdef était vrai, le fichier moc n'a pas été généré.
La suppression de tous les #ifdefs a donc résolu le problème.
Cette chose ne se produisait pas avec Windows et VS 2013.
la source
g++ *.cpp ...
. (Besoin de quelque chose de rapide et de sale mais qmake était plein de chagrin.)Si tout le reste échoue, recherchez la duplication. J'ai été mal orienté par la référence initiale explicite aux constructeurs et aux destructeurs jusqu'à ce que je lise une référence dans un autre post. C'est n'importe quelle méthode non résolue. Dans mon cas, je pensais avoir remplacé la déclaration qui utilisait char * xml comme paramètre par une utilisant le const inutilement gênant const * xml, mais à la place, j'en avais créé une nouvelle et laissé l'autre en place.
la source
Il existe de nombreuses possibilités mentionnées pour provoquer cette erreur, et je suis sûr que beaucoup d'entre elles provoquent l'erreur. Dans mon cas, il y avait une autre définition de la même classe, en raison d'une duplication du fichier source. Ce fichier a été compilé, mais pas lié, de sorte que l'éditeur de liens se plaignait de ne pas pouvoir le trouver.
Pour résumer, je dirais que si vous avez regardé la classe assez longtemps et que vous ne voyez pas quel problème de syntaxe possible pourrait en être la cause, recherchez les problèmes de construction comme un fichier manquant ou un fichier dupliqué.
la source
Dans mon cas, j'utilise Qt et j'avais défini une
QObject
sous - classe dans un fichierfoo.cpp
(pas.h
). Le correctif devait être ajouté#include "foo.moc"
à la fin defoo.cpp
.la source
Je pense qu'il vaut également la peine de mentionner que vous obtiendrez également le message lorsque vous essayez de créer un lien vers un objet de n'importe quelle classe qui a au moins une méthode virtuelle et l'éditeur de liens ne peut pas trouver le fichier. Par exemple:
Foo.hpp:
Foo.cpp:
Compilé avec:
Et main.cpp:
Compilé et lié avec:
Donne notre erreur préférée:
Cela se produit de mon incompréhensible parce que:
Vtable est créé par classe au moment de la compilation
L'éditeur de liens n'a pas accès à vtable qui se trouve dans Foo.o
la source
J'ai eu cette erreur dans le scénario suivant
Prenons un cas où vous avez défini l'implémentation des fonctions membres d'une classe dans le fichier d'en-tête lui-même. Ce fichier d'en-tête est un en-tête exporté (en d'autres termes, il peut être copié dans un fichier commun / inclus directement dans votre base de code). Vous avez maintenant décidé de séparer l'implémentation des fonctions membres dans un fichier .cpp. Après avoir séparé / déplacé l'implémentation vers .cpp, le fichier d'en-tête n'a plus que les prototypes des fonctions membres à l'intérieur de la classe. Après les modifications ci-dessus, si vous créez votre base de code, vous pouvez obtenir l'erreur "référence non définie à 'vtable ...".
Pour résoudre ce problème, avant de créer, assurez-vous de supprimer le fichier d'en-tête (auquel vous avez apporté des modifications) dans le répertoire commun / include. Assurez-vous également que vous modifiez votre makefile pour accueillir / ajouter le nouveau fichier .o qui est construit à partir du nouveau fichier .cpp que vous venez de créer. Lorsque vous effectuez ces étapes, le compilateur / éditeur de liens ne se plaindra plus.
la source
J'ai eu ce type d'erreur dans des situations où j'essayais de créer un lien vers un objet lorsque j'ai eu un bug de création qui empêchait l'objet d'être ajouté à l'archive.
Disons que j'ai libXYZ.a qui est censé avoir bioseq.o dans int mais il n'en a pas.
J'ai une erreur:
Ceci est différent de tout ce qui précède. J'appellerais cet objet manquant dans le problème d'archivage.
la source
Il est également possible que vous obteniez un message comme
si vous oubliez de définir une fonction virtuelle d'une classe FakeClass1 lorsque vous essayez de lier un test unitaire pour une autre classe SomeClass.
Et
Dans ce cas, je vous suggère de vérifier à nouveau votre faux pour class1. Vous constaterez probablement que vous avez peut-être oublié de définir une fonction virtuelle
ForgottenFunc
dans votre fausse classe.la source
J'ai eu cette erreur lorsque j'ai ajouté une deuxième classe à une paire source / en-tête existante. Deux en-têtes de classe dans le même fichier .h et définitions de fonctions pour deux classes dans le même fichier .cpp.
J'ai déjà fait cela avec succès auparavant, avec des classes qui sont censées travailler en étroite collaboration, mais apparemment, quelque chose ne m'a pas plu cette fois. Je ne sais toujours pas quoi, mais les diviser en une classe par unité de compilation l'a corrigé.
La tentative échouée:
_gui_icondata.h:
_gui_icondata.cpp:
Encore une fois, l'ajout d'une nouvelle paire source / en-tête et le copier / coller textuellement de la classe IconWithData "ont juste fonctionné".
la source
Mon cas était stupide, j'ai eu un supplément
"
après#include
par erreur et devinez quoi?Je me gratte la tête et le visage en palmatisant depuis des heures en commentant les fonctions virtuelles pour voir si quelque chose a changé, et enfin en supprimant le supplément
"
, tout a été corrigé! Ce genre de choses doit vraiment entraîner une erreur de compilation et non une erreur de liaison.Par extra
"
, je veux dire:la source
Dans mon cas, j'avais une classe de base nommée Person et deux classes dérivées nommées Student et Professor.
Comment mon programme a été corrigé: 1. J'ai créé toutes les fonctions de la classe de base
Pure Virtual.
2. J'ai utilisé tous les destructeurs virtuels commedefault ones.
la source
J'ai eu cette erreur simplement parce que le nom d'un argument constructeur différait dans le fichier d'en-tête et dans le fichier d'implémentation. La signature du constructeur est
et ce que j'ai écrit dans la mise en œuvre a commencé par
ainsi j'ai accidentellement remplacé "pset" par "ravageur". Le compilateur se plaignait de celui-ci et de deux autres constructeurs dans lesquels il n'y avait aucune erreur. J'utilise la version 4.9.1 de g ++ sous Ubuntu. Et la définition d'un destructeur virtuel dans cette classe dérivée n'a fait aucune différence (il est défini dans la classe de base). Je n'aurais jamais trouvé ce bogue si je n'avais pas collé les corps des constructeurs dans le fichier d'en-tête, les définissant ainsi en classe.
la source