j'ai ecrit une classe thread (suis pas le premier, hein ;-P) qui en fait contient une
fonction Run virtuelle pure qui doit etre redefini dans une classe dérivée. Rien
de vraiment difficile. Cette classe thread contient une fonction StartThread()
J'ai rajouté un booléen sur le constructeur du Thread. Si on lui passe true, il
demarre tout seul en appelant StartThread. Je me suis dit que de toute facon,
je ne peux pas instancier la classe Thread (car abstraite du fait du virtual ... = 0).
Le probleme qui se pose (sous g++ uniquement avec comme flags de compilation
-Werror -Wall -pedantic -std=c++98 -fPIC) c'est que je me retrouve avec
des erreurs (et pas a chacune des executions) du genre.
> pure virtual method called
> terminate called without an active exception
> Abort
A priori, pas de debordement ailleurs (je verifie encore) qui justifierait l'ecrasement
de la table des fonctions virtuelles. Des idées ? Notons que le meme mecanisme fonctionne
a merveille sous Visual Studio 2005. Peut-etre un flag a rajouter à g++ ?
Même réponse que d'habitude : identifie et poste le code _minimal_ qui reproduit le problème.
Toute l'attirail pour installer les choses se trouve ici : http://gforge.inria.fr/frs/?group_id63
Il faut scons pour compiler et libxml2... Sinon, vous trouverez la classe Thread ici : http://www.cijoint.fr/cij10255612339302.zip
Concernant la code posant (parfois) probleme : class Server : public Thread { int id; public: Server(int id): Thread(true), id(id) { } virtual void Run() { // ici n'importe quoi, ca change rien ! for(;;;) { Sleep(10); id++; } } };
void maint() { new Server(i); }
Voila. Doms.
Michel Decima
Bonjour,
j'ai ecrit une classe thread (suis pas le premier, hein ;-P) qui en fait contient une fonction Run virtuelle pure qui doit etre redefini dans une classe dérivée. Rien de vraiment difficile. Cette classe thread contient une fonction StartThread()
J'ai rajouté un booléen sur le constructeur du Thread. Si on lui passe true, il demarre tout seul en appelant StartThread. Je me suis dit que de toute facon, je ne peux pas instancier la classe Thread (car abstraite du fait du virtual ... = 0).
Le probleme qui se pose (sous g++ uniquement avec comme flags de compilation -Werror -Wall -pedantic -std=c++98 -fPIC) c'est que je me retrouve avec des erreurs (et pas a chacune des executions) du genre.
pure virtual method called terminate called without an active exception Abort
Si tu appelle une fonction membre virtuelle dans un constructeur d'une classe de base, c'est la version disponible dans la classe de base qui est appelee, pas celle de la classe derivee. Si la fonction est virtuelle pure, alors tu as un abort.
Ca peut paraitre tordu, mais c'est assez normal: le constructeur de la classe de base va etre appelé avant celle de la classe derivee, et la fonction virtuelle de la classe derivee utilise potentiellement des membre de cette classe dérivee, qui ne seraient pas initialises lors de l'appel par le constructeur de la base.
class Derived : public Base { public: virtual void func() { std::cout << "Derived" << std::endl; } };
int main() { Derived d; // Affichera "Base". }
Si je transforme Base::func() en fonction virtuelle pure, j'ai le message suivant avec g++ (sans options particulieres):
pipo.C: In constructor 'Base::Base()': pipo.C:6: warning: abstract virtual 'virtual void Base::func()' called from constructor ld: 0711-317 ERROR: Undefined symbol: .Base::func()
et xlC dit presque pareil:
"pipo.C", line 6.9: 1540-0285 (W) The expression calls the undefined pure virtual function "Base::func()". ld: 0711-317 ERROR: Undefined symbol: .Base::func()
A priori, pas de debordement ailleurs (je verifie encore) qui justifierait l'ecrasement de la table des fonctions virtuelles. Des idées ? Notons que le meme mecanisme fonctionne a merveille sous Visual Studio 2005. Peut-etre un flag a rajouter à g++ ?
Je dirais plutot qu'il faut trouver le flag necessaire a Visual Studio pour qu'il cesse de faire n'importe quoi.
Bonjour,
j'ai ecrit une classe thread (suis pas le premier, hein ;-P) qui en fait contient une
fonction Run virtuelle pure qui doit etre redefini dans une classe dérivée. Rien
de vraiment difficile. Cette classe thread contient une fonction StartThread()
J'ai rajouté un booléen sur le constructeur du Thread. Si on lui passe true, il
demarre tout seul en appelant StartThread. Je me suis dit que de toute facon,
je ne peux pas instancier la classe Thread (car abstraite du fait du virtual ... = 0).
Le probleme qui se pose (sous g++ uniquement avec comme flags de compilation
-Werror -Wall -pedantic -std=c++98 -fPIC) c'est que je me retrouve avec
des erreurs (et pas a chacune des executions) du genre.
pure virtual method called
terminate called without an active exception
Abort
Si tu appelle une fonction membre virtuelle dans un constructeur d'une
classe de base, c'est la version disponible dans la classe de base qui
est appelee, pas celle de la classe derivee. Si la fonction est
virtuelle pure, alors tu as un abort.
Ca peut paraitre tordu, mais c'est assez normal: le constructeur de la
classe de base va etre appelé avant celle de la classe derivee, et la
fonction virtuelle de la classe derivee utilise potentiellement des
membre de cette classe dérivee, qui ne seraient pas initialises lors
de l'appel par le constructeur de la base.
class Derived : public Base
{
public:
virtual void func() { std::cout << "Derived" << std::endl; }
};
int main() {
Derived d; // Affichera "Base".
}
Si je transforme Base::func() en fonction virtuelle pure, j'ai
le message suivant avec g++ (sans options particulieres):
pipo.C: In constructor 'Base::Base()':
pipo.C:6: warning: abstract virtual 'virtual void Base::func()' called
from constructor
ld: 0711-317 ERROR: Undefined symbol: .Base::func()
et xlC dit presque pareil:
"pipo.C", line 6.9: 1540-0285 (W) The expression calls the undefined
pure virtual function "Base::func()".
ld: 0711-317 ERROR: Undefined symbol: .Base::func()
A priori, pas de debordement ailleurs (je verifie encore) qui justifierait l'ecrasement
de la table des fonctions virtuelles. Des idées ? Notons que le meme mecanisme fonctionne
a merveille sous Visual Studio 2005. Peut-etre un flag a rajouter à g++ ?
Je dirais plutot qu'il faut trouver le flag necessaire a Visual Studio
pour qu'il cesse de faire n'importe quoi.
j'ai ecrit une classe thread (suis pas le premier, hein ;-P) qui en fait contient une fonction Run virtuelle pure qui doit etre redefini dans une classe dérivée. Rien de vraiment difficile. Cette classe thread contient une fonction StartThread()
J'ai rajouté un booléen sur le constructeur du Thread. Si on lui passe true, il demarre tout seul en appelant StartThread. Je me suis dit que de toute facon, je ne peux pas instancier la classe Thread (car abstraite du fait du virtual ... = 0).
Le probleme qui se pose (sous g++ uniquement avec comme flags de compilation -Werror -Wall -pedantic -std=c++98 -fPIC) c'est que je me retrouve avec des erreurs (et pas a chacune des executions) du genre.
pure virtual method called terminate called without an active exception Abort
Si tu appelle une fonction membre virtuelle dans un constructeur d'une classe de base, c'est la version disponible dans la classe de base qui est appelee, pas celle de la classe derivee. Si la fonction est virtuelle pure, alors tu as un abort.
Ca peut paraitre tordu, mais c'est assez normal: le constructeur de la classe de base va etre appelé avant celle de la classe derivee, et la fonction virtuelle de la classe derivee utilise potentiellement des membre de cette classe dérivee, qui ne seraient pas initialises lors de l'appel par le constructeur de la base.
class Derived : public Base { public: virtual void func() { std::cout << "Derived" << std::endl; } };
int main() { Derived d; // Affichera "Base". }
Si je transforme Base::func() en fonction virtuelle pure, j'ai le message suivant avec g++ (sans options particulieres):
pipo.C: In constructor 'Base::Base()': pipo.C:6: warning: abstract virtual 'virtual void Base::func()' called from constructor ld: 0711-317 ERROR: Undefined symbol: .Base::func()
et xlC dit presque pareil:
"pipo.C", line 6.9: 1540-0285 (W) The expression calls the undefined pure virtual function "Base::func()". ld: 0711-317 ERROR: Undefined symbol: .Base::func()
A priori, pas de debordement ailleurs (je verifie encore) qui justifierait l'ecrasement de la table des fonctions virtuelles. Des idées ? Notons que le meme mecanisme fonctionne a merveille sous Visual Studio 2005. Peut-etre un flag a rajouter à g++ ?
Je dirais plutot qu'il faut trouver le flag necessaire a Visual Studio pour qu'il cesse de faire n'importe quoi.
Fabien LE LEZ
On Wed, 4 Apr 2007 08:53:17 +0200, "Dominique Vaufreydaz" :
Il faut scons pour compiler et libxml2... Sinon, vous trouverez
Tu veux dire que l'erreur est cachée dans je ne sais combien de milliers de lignes de code, et impossible à reproduire dans un code plus simple ?
Dans ce cas, laisse tomber -- tu n'arriveras probablement jamais à identifier le problème.
On Wed, 4 Apr 2007 08:53:17 +0200, "Dominique Vaufreydaz"
<Doms@invalid>:
Il faut scons pour compiler et libxml2... Sinon, vous trouverez
Tu veux dire que l'erreur est cachée dans je ne sais combien de
milliers de lignes de code, et impossible à reproduire dans un code
plus simple ?
Dans ce cas, laisse tomber -- tu n'arriveras probablement jamais à
identifier le problème.
On Wed, 4 Apr 2007 08:53:17 +0200, "Dominique Vaufreydaz" :
Il faut scons pour compiler et libxml2... Sinon, vous trouverez
Tu veux dire que l'erreur est cachée dans je ne sais combien de milliers de lignes de code, et impossible à reproduire dans un code plus simple ?
Dans ce cas, laisse tomber -- tu n'arriveras probablement jamais à identifier le problème.
Dominique Vaufreydaz
Bonjour,
Si tu appelle une fonction membre virtuelle dans un constructeur d'une classe de base, c'est la version disponible dans la classe de base qui est appelee, pas celle de la classe derivee. Si la fonction est virtuelle pure, alors tu as un abort. Ca peut paraitre tordu, mais c'est assez normal: le constructeur de la classe de base va etre appelé avant celle de la classe derivee, et la fonction virtuelle de la classe derivee utilise potentiellement des membre de cette classe dérivee, qui ne seraient pas initialises lors de l'appel par le constructeur de la base.
C'est bien ce que je pensais... Le truc qui me gonfle quand meme c'est : - que ca plante aps tout le temps - que c'est pas dependant du code. Pour un meme exe, 2 executions successivent donnes 2 comportement différents. Notons que ca plante systematiquement si lancé via gdb ou valgrind...
Je dirais plutot qu'il faut trouver le flag necessaire a Visual Studio pour qu'il cesse de faire n'importe quoi.
Mouai. Perso, ca perd de l'interet le virtuel dans ce cas la (meme si c'est un peu particulier) et j'aurais aimé que l'initialisation des fonctions virtuelles soitent faites avant l'appel des constructeurs des classes meres...
Ca veut quand meme dire que le compilo devrait raler si on appelle des fonctions virtuelles (pure) dans le constructeur d'une classe. Ce que ne font pas ni cl (VS2005) ni g++...
Merci. Doms.
Bonjour,
Si tu appelle une fonction membre virtuelle dans un constructeur d'une
classe de base, c'est la version disponible dans la classe de base qui
est appelee, pas celle de la classe derivee. Si la fonction est
virtuelle pure, alors tu as un abort.
Ca peut paraitre tordu, mais c'est assez normal: le constructeur de la
classe de base va etre appelé avant celle de la classe derivee, et la
fonction virtuelle de la classe derivee utilise potentiellement des
membre de cette classe dérivee, qui ne seraient pas initialises lors
de l'appel par le constructeur de la base.
C'est bien ce que je pensais... Le truc qui me gonfle quand meme
c'est :
- que ca plante aps tout le temps
- que c'est pas dependant du code. Pour un meme exe, 2 executions
successivent donnes 2 comportement différents. Notons que
ca plante systematiquement si lancé via gdb ou valgrind...
Je dirais plutot qu'il faut trouver le flag necessaire a Visual Studio
pour qu'il cesse de faire n'importe quoi.
Mouai. Perso, ca perd de l'interet le virtuel dans ce cas la (meme
si c'est un peu particulier) et j'aurais aimé que l'initialisation des
fonctions virtuelles soitent faites avant l'appel des constructeurs des
classes meres...
Ca veut quand meme dire que le compilo devrait raler si on appelle
des fonctions virtuelles (pure) dans le constructeur d'une classe.
Ce que ne font pas ni cl (VS2005) ni g++...
Si tu appelle une fonction membre virtuelle dans un constructeur d'une classe de base, c'est la version disponible dans la classe de base qui est appelee, pas celle de la classe derivee. Si la fonction est virtuelle pure, alors tu as un abort. Ca peut paraitre tordu, mais c'est assez normal: le constructeur de la classe de base va etre appelé avant celle de la classe derivee, et la fonction virtuelle de la classe derivee utilise potentiellement des membre de cette classe dérivee, qui ne seraient pas initialises lors de l'appel par le constructeur de la base.
C'est bien ce que je pensais... Le truc qui me gonfle quand meme c'est : - que ca plante aps tout le temps - que c'est pas dependant du code. Pour un meme exe, 2 executions successivent donnes 2 comportement différents. Notons que ca plante systematiquement si lancé via gdb ou valgrind...
Je dirais plutot qu'il faut trouver le flag necessaire a Visual Studio pour qu'il cesse de faire n'importe quoi.
Mouai. Perso, ca perd de l'interet le virtuel dans ce cas la (meme si c'est un peu particulier) et j'aurais aimé que l'initialisation des fonctions virtuelles soitent faites avant l'appel des constructeurs des classes meres...
Ca veut quand meme dire que le compilo devrait raler si on appelle des fonctions virtuelles (pure) dans le constructeur d'une classe. Ce que ne font pas ni cl (VS2005) ni g++...
Merci. Doms.
Dominique Vaufreydaz
Salut,
Tu veux dire que l'erreur est cachée dans je ne sais combien de milliers de lignes de code, et impossible à reproduire dans un code plus simple ?
Non, que si tu veux tout, il te faut ca. Mais que ca merde qu'avec le Thread (qui utilise Event soit).
Dans ce cas, laisse tomber -- tu n'arriveras probablement jamais à identifier le problème.
Ben il faudrait bien car c'est moi qui ai fait ce code et que ca me gonfle ! Surtout que le pure virtual method call j'ai un peu l'impression que ca n'est pas vraiment de mon fait.
Reste que la reponse de Michel va dans le sens de ce que je pensais. C'est un peu l'aspect random des choses qui m'embete.
Merci. Doms.
Salut,
Tu veux dire que l'erreur est cachée dans je ne sais combien de
milliers de lignes de code, et impossible à reproduire dans un code
plus simple ?
Non, que si tu veux tout, il te faut ca. Mais que ca merde qu'avec
le Thread (qui utilise Event soit).
Dans ce cas, laisse tomber -- tu n'arriveras probablement jamais à
identifier le problème.
Ben il faudrait bien car c'est moi qui ai fait ce code et que ca me
gonfle ! Surtout que le pure virtual method call j'ai un peu l'impression
que ca n'est pas vraiment de mon fait.
Reste que la reponse de Michel va dans le sens de ce que je pensais.
C'est un peu l'aspect random des choses qui m'embete.
Tu veux dire que l'erreur est cachée dans je ne sais combien de milliers de lignes de code, et impossible à reproduire dans un code plus simple ?
Non, que si tu veux tout, il te faut ca. Mais que ca merde qu'avec le Thread (qui utilise Event soit).
Dans ce cas, laisse tomber -- tu n'arriveras probablement jamais à identifier le problème.
Ben il faudrait bien car c'est moi qui ai fait ce code et que ca me gonfle ! Surtout que le pure virtual method call j'ai un peu l'impression que ca n'est pas vraiment de mon fait.
Reste que la reponse de Michel va dans le sens de ce que je pensais. C'est un peu l'aspect random des choses qui m'embete.
Merci. Doms.
James Kanze
On Apr 4, 7:46 am, "Dominique Vaufreydaz" wrote:
j'ai ecrit une classe thread (suis pas le premier, hein ;-P) qui en fait contient une fonction Run virtuelle pure qui doit etre redefini dans une classe dérivée. Rien de vraiment difficile. Cette classe thread contient une fonction StartThread()
Ce n'est pas forcément une bonne idée. C'est le vieux argument du modèle stratégie contre le modèle template : dans ce cas-ci, je préfère nettement le modèle stratégie (qui permettrait aussi par la suite de fournir des wrapper templatés pour des fonctions ou des objets fonctionnels).
J'ai rajouté un booléen sur le constructeur du Thread. Si on lui passe true, il demarre tout seul en appelant StartThread.
Dans le constructeur de Thread ? Ça, c'est une très mauvaise idée. Tu veux démarrer le thread avant que l'objet qui l'implémente soit construit. (Curieusement, c'est une erreur fréquente. La première version de SwingHelper, pour Java, la faisait, par exemple.)
C'est une des raisons pourquoi je préfère de loin le modèle stratégie ici.
Je me suis dit que de toute facon, je ne peux pas instancier la classe Thread (car abstraite du fait du virtual ... = 0).
Le probleme qui se pose (sous g++ uniquement avec comme flags de comp ilation -Werror -Wall -pedantic -std=c++98 -fPIC) c'est que je me retrouve avec des erreurs (et pas a chacune des executions) du genre.
pure virtual method called terminate called without an active exception Abort
A priori, pas de debordement ailleurs (je verifie encore) qui justifierait l'ecrasement de la table des fonctions virtuelles. Des idées ?
C'est un comportement indéfini. Lors de la construction de Thread, le type dynamique de l'objet est Thread. Ce qui veut dire que la résolution dynamique trouve la version de la fonction dans Thread. Et la norme dit que si la résolution dynamique trouve une fonction virtuelle pûre, c'est un comportement indéfini (même si la fonction a une définition).
Notons que le meme mecanisme fonctionne a merveille sous Visual Studio 2005.
C'est probablement le résultat d'une optimisation. Le compilateur, sachant que la fonction est pûre virtuelle, et ne peut pas être appelée par la résolution dynamique dans le constructeur, se passe d'initialiser le vtable pour la classe de base, mais l'initialise immédiatement pour la classe dérivée.
Comme j'ai dit, en revanche, c'est un comportement indéfini. Tu ne peux pas y compter. Et dans ce cas-ci, tu ne veux pas t'y compter non plus, parce que tu risques fort que la fonction s'exécute sur l'objet avant même qu'on y est entré dans son constructeur. (Ça dépend en fait du scheduleur ; je pourrais bien imaginer un algorithme de scheduling où ça marcherait 99,9% des fois, pour échouer 0,1%. C-à-d que ça marcherait dans tous tes tests, pour échouer deux fois de suite lors de la démo ultra-importante devant le client.)
Peut-etre un flag a rajouter à g++ ?
Dans ce cas-ci, je crois que le comportement de g++ est le mieux. Il ne te laisse pas croire que ça marche.
-- James Kanze (GABI Software) email: 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
On Apr 4, 7:46 am, "Dominique Vaufreydaz" <Doms@invalid> wrote:
j'ai ecrit une classe thread (suis pas le premier, hein
;-P) qui en fait contient une fonction Run virtuelle pure
qui doit etre redefini dans une classe dérivée. Rien de
vraiment difficile. Cette classe thread contient une
fonction StartThread()
Ce n'est pas forcément une bonne idée. C'est le vieux argument
du modèle stratégie contre le modèle template : dans ce cas-ci,
je préfère nettement le modèle stratégie (qui permettrait aussi
par la suite de fournir des wrapper templatés pour des fonctions
ou des objets fonctionnels).
J'ai rajouté un booléen sur le constructeur du Thread. Si
on lui passe true, il demarre tout seul en appelant
StartThread.
Dans le constructeur de Thread ? Ça, c'est une très mauvaise
idée. Tu veux démarrer le thread avant que l'objet qui
l'implémente soit construit. (Curieusement, c'est une erreur
fréquente. La première version de SwingHelper, pour Java, la
faisait, par exemple.)
C'est une des raisons pourquoi je préfère de loin le modèle
stratégie ici.
Je me suis dit que de toute facon, je ne peux
pas instancier la classe Thread (car abstraite du fait du
virtual ... = 0).
Le probleme qui se pose (sous g++ uniquement avec comme flags de comp ilation
-Werror -Wall -pedantic -std=c++98 -fPIC) c'est que je me retrouve avec
des erreurs (et pas a chacune des executions) du genre.
pure virtual method called
terminate called without an active exception
Abort
A priori, pas de debordement ailleurs (je verifie encore)
qui justifierait l'ecrasement de la table des fonctions
virtuelles. Des idées ?
C'est un comportement indéfini. Lors de la construction de
Thread, le type dynamique de l'objet est Thread. Ce qui veut
dire que la résolution dynamique trouve la version de la
fonction dans Thread. Et la norme dit que si la résolution
dynamique trouve une fonction virtuelle pûre, c'est un
comportement indéfini (même si la fonction a une définition).
Notons que le meme mecanisme
fonctionne a merveille sous Visual Studio 2005.
C'est probablement le résultat d'une optimisation. Le
compilateur, sachant que la fonction est pûre virtuelle, et ne
peut pas être appelée par la résolution dynamique dans le
constructeur, se passe d'initialiser le vtable pour la classe de
base, mais l'initialise immédiatement pour la classe dérivée.
Comme j'ai dit, en revanche, c'est un comportement indéfini. Tu
ne peux pas y compter. Et dans ce cas-ci, tu ne veux pas t'y
compter non plus, parce que tu risques fort que la fonction
s'exécute sur l'objet avant même qu'on y est entré dans son
constructeur. (Ça dépend en fait du scheduleur ; je pourrais
bien imaginer un algorithme de scheduling où ça marcherait 99,9%
des fois, pour échouer 0,1%. C-à-d que ça marcherait dans tous
tes tests, pour échouer deux fois de suite lors de la démo
ultra-importante devant le client.)
Peut-etre
un flag a rajouter à g++ ?
Dans ce cas-ci, je crois que le comportement de g++ est le
mieux. Il ne te laisse pas croire que ça marche.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
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
j'ai ecrit une classe thread (suis pas le premier, hein ;-P) qui en fait contient une fonction Run virtuelle pure qui doit etre redefini dans une classe dérivée. Rien de vraiment difficile. Cette classe thread contient une fonction StartThread()
Ce n'est pas forcément une bonne idée. C'est le vieux argument du modèle stratégie contre le modèle template : dans ce cas-ci, je préfère nettement le modèle stratégie (qui permettrait aussi par la suite de fournir des wrapper templatés pour des fonctions ou des objets fonctionnels).
J'ai rajouté un booléen sur le constructeur du Thread. Si on lui passe true, il demarre tout seul en appelant StartThread.
Dans le constructeur de Thread ? Ça, c'est une très mauvaise idée. Tu veux démarrer le thread avant que l'objet qui l'implémente soit construit. (Curieusement, c'est une erreur fréquente. La première version de SwingHelper, pour Java, la faisait, par exemple.)
C'est une des raisons pourquoi je préfère de loin le modèle stratégie ici.
Je me suis dit que de toute facon, je ne peux pas instancier la classe Thread (car abstraite du fait du virtual ... = 0).
Le probleme qui se pose (sous g++ uniquement avec comme flags de comp ilation -Werror -Wall -pedantic -std=c++98 -fPIC) c'est que je me retrouve avec des erreurs (et pas a chacune des executions) du genre.
pure virtual method called terminate called without an active exception Abort
A priori, pas de debordement ailleurs (je verifie encore) qui justifierait l'ecrasement de la table des fonctions virtuelles. Des idées ?
C'est un comportement indéfini. Lors de la construction de Thread, le type dynamique de l'objet est Thread. Ce qui veut dire que la résolution dynamique trouve la version de la fonction dans Thread. Et la norme dit que si la résolution dynamique trouve une fonction virtuelle pûre, c'est un comportement indéfini (même si la fonction a une définition).
Notons que le meme mecanisme fonctionne a merveille sous Visual Studio 2005.
C'est probablement le résultat d'une optimisation. Le compilateur, sachant que la fonction est pûre virtuelle, et ne peut pas être appelée par la résolution dynamique dans le constructeur, se passe d'initialiser le vtable pour la classe de base, mais l'initialise immédiatement pour la classe dérivée.
Comme j'ai dit, en revanche, c'est un comportement indéfini. Tu ne peux pas y compter. Et dans ce cas-ci, tu ne veux pas t'y compter non plus, parce que tu risques fort que la fonction s'exécute sur l'objet avant même qu'on y est entré dans son constructeur. (Ça dépend en fait du scheduleur ; je pourrais bien imaginer un algorithme de scheduling où ça marcherait 99,9% des fois, pour échouer 0,1%. C-à-d que ça marcherait dans tous tes tests, pour échouer deux fois de suite lors de la démo ultra-importante devant le client.)
Peut-etre un flag a rajouter à g++ ?
Dans ce cas-ci, je crois que le comportement de g++ est le mieux. Il ne te laisse pas croire que ça marche.
-- James Kanze (GABI Software) email: 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
Guillaume GOURDIN
Ce n'est pas forcément une bonne idée. C'est le vieux argument du modèle stratégie contre le modèle template
Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
Ce n'est pas forcément une bonne idée. C'est le vieux argument
du modèle stratégie contre le modèle template
Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
Ce n'est pas forcément une bonne idée. C'est le vieux argument du modèle stratégie contre le modèle template
Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
Jean-Marc Bourguet
Guillaume GOURDIN writes:
Ce n'est pas forcément une bonne idée. C'est le vieux argument du modèle stratégie contre le modèle template
Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
"Il n'y est pas de probleme qui ne puisse etre resolu par une indirection de plus."
En gros, le modele template permet d'adapter le fonctionnement d'une classe en substituant des membres virtuels. Le modele strategie permet d'adapter le fonctionnement d'une classe en lui donnant en parametre une autre classe contenant (uniquement?) les membres qui sont adaptables. Il est plus complique, mais plus souple.
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
Guillaume GOURDIN <gourdin@liw.fr> writes:
Ce n'est pas forcément une bonne idée. C'est le vieux argument
du modèle stratégie contre le modèle template
Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
"Il n'y est pas de probleme qui ne puisse etre resolu par une indirection
de plus."
En gros, le modele template permet d'adapter le fonctionnement d'une classe
en substituant des membres virtuels. Le modele strategie permet d'adapter
le fonctionnement d'une classe en lui donnant en parametre une autre classe
contenant (uniquement?) les membres qui sont adaptables. Il est plus
complique, mais plus souple.
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
Ce n'est pas forcément une bonne idée. C'est le vieux argument du modèle stratégie contre le modèle template
Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
"Il n'y est pas de probleme qui ne puisse etre resolu par une indirection de plus."
En gros, le modele template permet d'adapter le fonctionnement d'une classe en substituant des membres virtuels. Le modele strategie permet d'adapter le fonctionnement d'une classe en lui donnant en parametre une autre classe contenant (uniquement?) les membres qui sont adaptables. Il est plus complique, mais plus souple.
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
Laurent Deniau
Jean-Marc Bourguet wrote:
Guillaume GOURDIN writes:
Ce n'est pas forcément une bonne idée. C'est le vieux argument du modèle stratégie contre le modèle template Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
"Il n'y est pas de probleme qui ne puisse etre resolu par une indirection de plus."
En gros, le modele template permet d'adapter le fonctionnement d'une classe en substituant des membres virtuels. Le modele strategie permet d'adapter le fonctionnement d'une classe en lui donnant en parametre une autre classe contenant (uniquement?) les membres qui sont adaptables. Il est plus complique, mais plus souple.
Sans compter que le second est configurable au runtime, ce qui peut s'averer utile dans le cas de la gestion de threads.
a+, ld.
Jean-Marc Bourguet wrote:
Guillaume GOURDIN <gourdin@liw.fr> writes:
Ce n'est pas forcément une bonne idée. C'est le vieux argument
du modèle stratégie contre le modèle template
Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
"Il n'y est pas de probleme qui ne puisse etre resolu par une indirection
de plus."
En gros, le modele template permet d'adapter le fonctionnement d'une classe
en substituant des membres virtuels. Le modele strategie permet d'adapter
le fonctionnement d'une classe en lui donnant en parametre une autre classe
contenant (uniquement?) les membres qui sont adaptables. Il est plus
complique, mais plus souple.
Sans compter que le second est configurable au runtime, ce qui peut
s'averer utile dans le cas de la gestion de threads.
Ce n'est pas forcément une bonne idée. C'est le vieux argument du modèle stratégie contre le modèle template Pourrais-je te demander ce que sont ces 2 modèles stp? Merci!
"Il n'y est pas de probleme qui ne puisse etre resolu par une indirection de plus."
En gros, le modele template permet d'adapter le fonctionnement d'une classe en substituant des membres virtuels. Le modele strategie permet d'adapter le fonctionnement d'une classe en lui donnant en parametre une autre classe contenant (uniquement?) les membres qui sont adaptables. Il est plus complique, mais plus souple.
Sans compter que le second est configurable au runtime, ce qui peut s'averer utile dans le cas de la gestion de threads.