X is not a direct base of Y

Le
Pierre THIERRY
J'ai une erreur qui m'est assez sybilline, lorsque j'ai fait un peu de
refactoring sur une hiérarchie de classes. J'ai l'erreur de compilation
suivante :

dice.h: In constructor `libgames::Reroll_On_Value_Die::Reroll_On_Value_Die(int,
int)':
dice.h:111: error: type `class libgames::Die' is not a direct base of `
libgames::Reroll_On_Value_Die'

Sachant que ce constructeur se limite à :

Reroll_On_Value_Die(int faces = default_faces, int reroll_value = 0) : Die(faces), m_reroll_value(reroll_value) {}

Avec la hiérarchie :

- class Rollable
- class Die : public Rollable
- class Reroll_Die : public Die
- class Reroll_On_Value_Die : public Reroll_Die

Il me semblait qu'on pouvait appeler le constructeur d'une classe dans
une descendante non directe. D'ailleurs j'ai écrit un code porrof of
concept qui le fait très bien

Est-ce que quelqu'un voit d'où ça peut venir ?

Dubitativement,
Nowhere man
--
nowhere.man@levallois.eu.org
OpenPGP 0xD9D50D8A
  • Partager ce contenu :
Vos réponses
Trier par : date / pertinence
Pierre THIERRY
Le #248094
Le Sat, 21 May 2005 12:03:39 -0700, Ahmed MOHAMED ALI a écrit :
Il me semblait qu'on pouvait appeler le constructeur d'une classe
dans une descendante non directe. D'ailleurs j'ai écrit un code
porrof of concept qui le fait très bien...
Ah bon ?



Ha non. Je m'étais planté dans mon petit bout de code. J'avais deux
classes qui dérivent d'une première, pas la troisième de la deuxième et
la deuxième de la première.

Par contre, j'allais rétorquer « mais comment faire quand il y a une
classe abstraite dans la hiérarchie ? ». Je pensais qu'une classe non
instanciable ne pouvait pas avoir de constructeur.

Je viens de découvrir que si... ;-)

Par contre, du coup, je tombe sur une autre erreur, que j'avais déjà
rencontré avant :

test.o(.gnu.linkonce.t._ZN8libgames24Reroll_Once_If_Value_DieD1Ev+0xb): In function `libgames::Reroll_Once_If_Value_Die::~Reroll_Once_If_Value_Die [in-charge]()':
: undefined reference to `vtable for libgames::Reroll_Once_If_Value_Die'
test.o(.gnu.linkonce.t._ZN8libgames24Reroll_Once_If_Value_DieC1Eii+0x24): In function `libgames::Reroll_Once_If_Value_Die::Reroll_Once_If_Value_Die[in-charge](int, int)':
: undefined reference to `vtable for libgames::Reroll_Once_If_Value_Die'

Sachant que test.cpp est un petit programme qui essaie les dés. Ça
arrive évidemment au moment de l'édition des liens. Le constructeur se
limite à ça :

Reroll_Once_If_Value_Die
(int faces = default_faces, int reroll_value = 0)
: Reroll_On_Value_Die(faces, reroll_value) {}

Il y a une méthode virtuelle dès la première classe de la hiérarchie
(rapport à la vtable qui manquerait ?).

Incompréhensiblement,
Nowhere man
--

OpenPGP 0xD9D50D8A


Horst Kraemer
Le #248093
Pierre THIERRY
Le Sat, 21 May 2005 12:03:39 -0700, Ahmed MOHAMED ALI a écrit :
Il me semblait qu'on pouvait appeler le constructeur d'une classe
dans une descendante non directe. D'ailleurs j'ai écrit un code
porrof of concept qui le fait très bien...
Ah bon ?



Ha non. Je m'étais planté dans mon petit bout de code. J'avais deux
classes qui dérivent d'une première, pas la troisième de la deuxième et
la deuxième de la première.

Par contre, j'allais rétorquer « mais comment faire quand il y a une
classe abstraite dans la hiérarchie ? ». Je pensais qu'une classe non
instanciable ne pouvait pas avoir de constructeur.

Je viens de découvrir que si... ;-)

Par contre, du coup, je tombe sur une autre erreur, que j'avais déjà
rencontré avant :

test.o(.gnu.linkonce.t._ZN8libgames24Reroll_Once_If_Value_DieD1Ev+0xb): In function `libgames::Reroll_Once_If_Value_Die::~Reroll_Once_If_Value_Die [in-charge]()':
: undefined reference to `vtable for libgames::Reroll_Once_If_Value_Die'
test.o(.gnu.linkonce.t._ZN8libgames24Reroll_Once_If_Value_DieC1Eii+0x24): In function `libgames::Reroll_Once_If_Value_Die::Reroll_Once_If_Value_Die[in-charge](int, int)':
: undefined reference to `vtable for libgames::Reroll_Once_If_Value_Die'

Sachant que test.cpp est un petit programme qui essaie les dés. Ça
arrive évidemment au moment de l'édition des liens. Le constructeur se
limite à ça :

Reroll_Once_If_Value_Die
(int faces = default_faces, int reroll_value = 0)
: Reroll_On_Value_Die(faces, reroll_value) {}

Il y a une méthode virtuelle dès la première classe de la hiérarchie
(rapport à la vtable qui manquerait ?).


Ce message indique normalement qu'il y une déclaration d'une fonction
virtuelle sans définition.

p.ex.

struct A
{
virtual void foo() {}
virtual ~A() {}
};

struct B:A
{
void foo();
};

int main() { B b; }

Il faut une implémentation de B::foo même si foo n'est jamais appelé.

--
Horst

--
Lâche pas la patate!



Ahmed MOHAMED ALI
Le #248090
Bonjour,

Il me semblait qu'on pouvait appeler le constructeur d'une classe dans
une descendante non directe. D'ailleurs j'ai écrit un code porrof of
concept qui le fait très bien...


Ah bon ?
Il ya un seul cas où tu peux le faire (c'est même obligatoire): c'est
lorsque tu hérites d'une base virtuelle.
Dans ce cas, c'est la classe la plus basse dans la hiérarchie qui appelle le
constructeur dans sa liste d'initialisation.

Ahmed

"Pierre THIERRY" news:
J'ai une erreur qui m'est assez sybilline, lorsque j'ai fait un peu de
refactoring sur une hiérarchie de classes. J'ai l'erreur de compilation
suivante :

dice.h: In constructor
`libgames::Reroll_On_Value_Die::Reroll_On_Value_Die(int,

int)':
dice.h:111: error: type `class libgames::Die' is not a direct base of `
libgames::Reroll_On_Value_Die'

Sachant que ce constructeur se limite à :

Reroll_On_Value_Die(int faces = default_faces, int reroll_value = 0) :
Die(faces), m_reroll_value(reroll_value) {}


Avec la hiérarchie :

- class Rollable
- class Die : public Rollable
- class Reroll_Die : public Die
- class Reroll_On_Value_Die : public Reroll_Die

Il me semblait qu'on pouvait appeler le constructeur d'une classe dans
une descendante non directe. D'ailleurs j'ai écrit un code porrof of
concept qui le fait très bien...

Est-ce que quelqu'un voit d'où ça peut venir ?

Dubitativement,
Nowhere man
--

OpenPGP 0xD9D50D8A



kanze
Le #247982
Pierre THIERRY wrote:

Par contre, du coup, je tombe sur une autre erreur, que
j'avais déjà rencontré avant :


test.o(.gnu.linkonce.t._ZN8libgames24Reroll_Once_If_Value_DieD1Ev+0xb):

In function
`libgames::Reroll_Once_If_Value_Die::~Reroll_Once_If_Value_Die
[in-charge]()':
: undefined reference to `vtable for
libgames::Reroll_Once_If_Value_Die'


test.o(.gnu.linkonce.t._ZN8libgames24Reroll_Once_If_Value_DieC1Eii+0x24):

In function
`libgames::Reroll_Once_If_Value_Die::Reroll_Once_If_Value_Die[in-charge](in t,
int)':
: undefined reference to `vtable for
libgames::Reroll_Once_If_Value_Die'


Sachant que test.cpp est un petit programme qui essaie les
dés. Ça arrive évidemment au moment de l'édition des liens.


Le problème ici, c'est que l'éditeur de liens ne trouve pas le
vtable.

Dans le temps, beaucoup de compilateurs mettaient le vtable dans
la module qui contenait la première fonction virtuelle définie
dans la classe. Vérifier bien que tu as défini cette fonction
(ainsi que toutes les fonctions virtuelles), et que l'éditeur de
liens puisse trouver la module où tu l'as définie.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Pierre THIERRY
Le #247912
Le Sat, 21 May 2005 15:44:16 +0200, Horst Kraemer a écrit :
Ce message indique normalement qu'il y une déclaration d'une fonction
virtuelle sans définition.


C'était ça. Maintenant, tout marche parfaitement. Merci à tous. J'ai
donc écrit les 5% de code (l'algo), reste à écrire les 75% de
l'interface et les 20% de gestion des entrées... ;-)

Courageusement,
Nowhere man
--

OpenPGP 0xD9D50D8A

Poster une réponse
Anonyme