Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Méthode pure appelée dans sa classe

12 réponses
Avatar
Stéphane
Bonjour,

Je suis confronté à un petit problème et je suis certain qu'il y a quelqu'un
ici qui pourra m'expliquer pourquoi cela n'est pas possible. Voici un petit
exemple de code:

/************************* Début du code ***************************/
#include <stdio.h>
class A
{
public:
A()
{
methodeAbstraite();
}

virtual ~A() {};
virtual methodeAbstraite(void) = 0;
};

class B : public A
{
public:
B():A() {};
virtual ~B() {};

virtual methodeAbstraite(void)
{
printf("Super !!!!\n");
}
};

void main(void)
{
B *b = new B();
}
/************************* Fin du code ***************************/

Au final, j'obtiens une belle erreur avec Visual C++ au moment du link:
main.obj : error LNK2001: unresolved external symbol "public: virtual int
__thiscall A::methodeAbstraite(void)" (?methodeAbstraite@A@@UAEHXZ)
Debug/abstract.exe : fatal error LNK1120: 1 unresolved externals

N'est-il pas possible d'appeler une méthode abstraite à partir de la classe
ou elle a été déclarée ?

Merci pour votre aide.
Stéphane VANPOPERYNGHE

--
MINOTAUR (un projet francophone de CMS en PHP/MySQL)
N'hésitez pas à rejoindre le projet et participer ainsi aux logiciels
libres.
http://projects.freelinuxdev.net/minotaur/

10 réponses

1 2
Avatar
Jean-Marc Bourguet
"Stéphane" writes:

N'est-il pas possible d'appeler une méthode abstraite à partir de la classe
ou elle a été déclarée ?


Une fonction membre virtuelle abstraite (on ne parle normalement pas
de methode en C++) doit simplement etre redefinie dans tous les
descendants. Elle peut etre appelee soit explicitement, soit
justement dans le constructeur et le destructeur parce qu'en C++,
durant l'execution du constructeur et du destructeur, un objet est du
type dynamique indique par le cteur/dteur et non du type dynamque de
l'objet le plus derive.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Stéphane
"Jean-Marc Bourguet" a écrit dans le message de
news:
"Stéphane" writes:

Une fonction membre virtuelle abstraite (on ne parle normalement pas
de methode en C++) doit simplement etre redefinie dans tous les
descendants. Elle peut etre appelee soit explicitement, soit
justement dans le constructeur et le destructeur parce qu'en C++,
durant l'execution du constructeur et du destructeur, un objet est du
type dynamique indique par le cteur/dteur et non du type dynamque de
l'objet le plus derive.



J'explique ce que j'essaye de faire je pense que cela sera plus simple.

Je voudrais avoir un objet de base servant à l'importation de fichiers 3D.
J'ai une classe de base CFileImport servant à appeler les fonctions
d'ouverture, de lecture et de fermeture du fichier et des classes filles
(CFileImportObj, CFileImport3ds, CFileImportLwo, ...) avec leurs propres
fonctions d'ouverture et de lecture.

Comme il existe des fichiers binaires et textuels, je voudrais avoir une
fonction membre openFile abstraite dans CFileImport. Dans chaque classe
enfant, on définie cette fonction pour faire l'ouverture spécifique du type
de fichier souhaité. Dans le constructeur de CFileImport, je voulais donc
appeler la méthode openFile de la classe enfant. Je voulais également faire
de même avec la fonction de lecture.

Si ce n'est pas possible comme j'essaye de le faire, existe-t-il une
solution similaire mais qui fonctionne :-) ?

Cordialement,
Stéphane VANPOPERYNGHE

--
MINOTAUR (un projet francophone de CMS en PHP/MySQL)
N'hésitez pas à rejoindre le projet et participer ainsi aux logiciels
libres.
http://projects.freelinuxdev.net/minotaur/

Avatar
Vincent Lascaux
Elle peut etre appelee soit explicitement, soit
justement dans le constructeur et le destructeur parce qu'en C++,
durant l'execution du constructeur et du destructeur, un objet est du
type dynamique indique par le cteur/dteur et non du type dynamque de
l'objet le plus derive.


On ne peut pas appeler depuis le constructeur ou le destructeur une fonction
virtuelle pure car :
- pour le constructeur, l'objet dérivé n'est pas encore construit
- pour le destructeur, l'objet dérivé est déjà détruit

--
Vincent

Avatar
Stéphane
On vient de me donner la solution.
Il faut simplement que je passe par une fonction membre de ma classe mère à
appeler après l'instanciation de ma classe fille.

Merci pour votre aide. C'est pas toujours simple mais cela va rentrer petit
à petit :-)

Stéphane

--
MINOTAUR (un projet francophone de CMS en PHP/MySQL)
N'hésitez pas à rejoindre le projet et participer ainsi aux logiciels libres
Avatar
Christophe de Vienne
Jean-Marc Bourguet wrote:


Si dans un constructeur/destructeur tu appelles directement un membre
virtuel pur, son code est exécuté (c'est le cas de l'OP).


Il semblait pourtant que l'OP avait un problème au link ?

--
Christophe de Vienne
Experience is something you don't get until just after you need it.
Oliver's Law.

Avatar
Jean-Marc Bourguet
Christophe de Vienne writes:

Jean-Marc Bourguet wrote:


Si dans un constructeur/destructeur tu appelles directement un membre
virtuel pur, son code est exécuté (c'est le cas de l'OP).


Il semblait pourtant que l'OP avait un problème au link ?


Parce qu'il ne fournissait pas de definition pour ce membre.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Christophe de Vienne
Jean-Marc Bourguet wrote:

Christophe de Vienne writes:

Jean-Marc Bourguet wrote:


Si dans un constructeur/destructeur tu appelles directement un membre
virtuel pur, son code est exécuté (c'est le cas de l'OP).


Il semblait pourtant que l'OP avait un problème au link ?


Parce qu'il ne fournissait pas de definition pour ce membre.



Mais la définition qu'il donne contient bien '= 0', comment se fait-il que
le compilateur ne donne pas un message du style "ne peut appeler une
fonction virtuelle pure" ?

A+

Christophe

--
Christophe de Vienne
Experience is something you don't get until just after you need it.
Oliver's Law.



Avatar
Jean-Marc Bourguet
Christophe de Vienne writes:

Jean-Marc Bourguet wrote:

Christophe de Vienne writes:

Jean-Marc Bourguet wrote:


Si dans un constructeur/destructeur tu appelles directement un membre
virtuel pur, son code est exécuté (c'est le cas de l'OP).


Il semblait pourtant que l'OP avait un problème au link ?


Parce qu'il ne fournissait pas de definition pour ce membre.



Mais la définition qu'il donne contient bien '= 0', comment se fait-il que
le compilateur ne donne pas un message du style "ne peut appeler une
fonction virtuelle pure" ?


Parce qu'on peut appeler une virtuelle pure explicitement et c'est ce
qu'il faisait dans son constructeur.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org




Avatar
kanze
Jean-Marc Bourguet wrote in message
news:...
"Vincent Lascaux" writes:

Elle peut etre appelee soit explicitement, soit justement dans le
constructeur et le destructeur parce qu'en C++, durant l'execution
du constructeur et du destructeur, un objet est du type dynamique
indique par le cteur/dteur et non du type dynamque de l'objet le
plus derive.


On ne peut pas appeler depuis le constructeur ou le destructeur une
fonction virtuelle pure car :
- pour le constructeur, l'objet dérivé n'est pas encore construit
- pour le destructeur, l'objet dérivé est déjà détruit


Si dans un constructeur/destructeur tu appelles directement un membre
virtuel pur, son code est exécuté (c'est le cas de l'OP).


Ce n'était pas le cas de l'OP. Dans son constructeur, il appelait :

methodAbstrait() ;

et non :

A::methodAbstrait() ;

Or, constructeur ou non, le premier suppose une résolution dynamique
(que le compilateur peut typiquement optimisé, parce que lors de la
construction, le type dynamique correspond au type dont on execute le
constructeur). Un appel dynamique à une fonction pûre virtuelle
(seulement possible dans un constructeur ou dans un destructeur) est un
comportement indéfini. C'est le cas dans le code de l'OP.

Ce que j'ai oublié de préciser, c'est que si dans un
constructeur/destructeur tu appelles une fonction qui appelle
virutellement (cad sans qualification explicite) un membre virtuel
pur, le comportement est indéfini.


Or que c'est le cas en question.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16



Avatar
Jean-Marc Bourguet
writes:

Ce n'était pas le cas de l'OP. Dans son constructeur, il appelait :

methodAbstrait() ;

et non :

A::methodAbstrait() ;

Or, constructeur ou non, le premier suppose une résolution dynamique


Il me semblait que non (dans le constructeur/destructeur les regles du
C++ sont en tout cas telles qu'il est possible de determiner
statiquement la fonction appelee) mais je peux me tromper (et 10.4/2
le laisse croire) et j'ai pas le temps de faire une exegese plus
profonde.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

1 2