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();
}
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/
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
Jean-Marc Bourguet <jm@bourguet.org> wrote in message
news:<pxbu19degjm.fsf@news.bourguet.org>...
kanze@gabi-soft.fr 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:kanze@gabi-soft.fr
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
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
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
Jean-Marc Bourguet <jm@bourguet.org> wrote in message
news:<pxb3cgxfzmm.fsf@news.bourguet.org>...
Christophe de Vienne <cdevienne@alphacent.com> writes:
Jean-Marc Bourguet wrote:
Christophe de Vienne <cdevienne@alphacent.com> 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:kanze@gabi-soft.fr
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
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