OVH Cloud OVH Cloud

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/

2 réponses

1 2
Avatar
kanze
Jean-Marc Bourguet wrote in message
news:...
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.


La norme dit que la résolution est dynamique, selon le type actuel. Il
s'avère qu'en effet, dans le constructeur même, le compilateur connaît
le type dynamique, et des optimisations sont possible. N'empèche que si
la fonction est définie, la forme A::methodAbstrait() est garantie de la
trouver, parce que la résolution est statique, tandis que sans le A::,
on a un comportement indéfini, parce que la résolution est dynamiqu --
et appeler une fonction pûre virtuelle à travers une résolution
dynamique donne toujours un comportement indéfini.

--
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
kanze
Jean-Marc Bourguet wrote in message
news:...
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.


Parce qu'il ne l'a pas appelée explicitement, ce qui donne un
comportement indéfini -- on peut avoir une erreur à l'édition de liens,
comme on peut avoir un appel à avort() lors de l'execution. Dans les
compilateurs que j'ai, Sun CC remplace l'appel par un no-op, et g++
donne une erreur déjà lors de la compilation ; je suis sûr aussi d'avoir
utiliser un compilateur qui appeler abort lors de l'execution (peut-être
un g++ très ancien). Aucun problème : tous ces comportements sont
autorisés par la norme.

--
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





1 2