j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Actuellement, je prends une référence sur cet objet,
j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Actuellement, je prends une référence sur cet objet,
j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Actuellement, je prends une référence sur cet objet,
Marc Boyer writes:j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Generalement ca arrive quand on appelle un membre virtuel dans le
constructeur ou le destructeur d'un objet.
Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Comme tous les temporaires qui ne sont pas bindé a une variable reference:
jusqu'a la fin de l'expression.
Actuellement, je prends une référence sur cet objet,
Si tu la conserve au dela du constructeur de x (comme le laisse croire la
suite), c'est fort possible que ce soit la source de ton probleme (et on ne
se retrouve pas dans le cas general mais vraissemblablement tu appelles le
membre virtuel apres la fin de l'execution du destructeur de Y(1)).
Marc Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> writes:
j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Generalement ca arrive quand on appelle un membre virtuel dans le
constructeur ou le destructeur d'un objet.
Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Comme tous les temporaires qui ne sont pas bindé a une variable reference:
jusqu'a la fin de l'expression.
Actuellement, je prends une référence sur cet objet,
Si tu la conserve au dela du constructeur de x (comme le laisse croire la
suite), c'est fort possible que ce soit la source de ton probleme (et on ne
se retrouve pas dans le cas general mais vraissemblablement tu appelles le
membre virtuel apres la fin de l'execution du destructeur de Y(1)).
Marc Boyer writes:j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Generalement ca arrive quand on appelle un membre virtuel dans le
constructeur ou le destructeur d'un objet.
Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Comme tous les temporaires qui ne sont pas bindé a une variable reference:
jusqu'a la fin de l'expression.
Actuellement, je prends une référence sur cet objet,
Si tu la conserve au dela du constructeur de x (comme le laisse croire la
suite), c'est fort possible que ce soit la source de ton probleme (et on ne
se retrouve pas dans le cas general mais vraissemblablement tu appelles le
membre virtuel apres la fin de l'execution du destructeur de Y(1)).
Marc Boyer writes:j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Generalement ca arrive quand on appelle un membre virtuel dans le
constructeur ou le destructeur d'un objet.
Là, ce doit être après la desctruction de l'objet.Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Comme tous les temporaires qui ne sont pas bindé a une variable reference:
jusqu'a la fin de l'expression.
Oui, et ici, l'expression termine à la fin du constructeur de x( );Actuellement, je prends une référence sur cet objet,
Si tu la conserve au dela du constructeur de x (comme le laisse croire la
suite), c'est fort possible que ce soit la source de ton probleme (et on ne
se retrouve pas dans le cas general mais vraissemblablement tu appelles le
membre virtuel apres la fin de l'execution du destructeur de Y(1)).
Oui, c'est ça. Ce qui est déstabilisant, c'est que ça fait partie
des trucs qui arrivent 'parfois'. En fait, j'avais fait un exemple
minimal à poster ici, et sur l'exemple, ça plante pas.
Merci.
#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
Marc Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> writes:
j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Generalement ca arrive quand on appelle un membre virtuel dans le
constructeur ou le destructeur d'un objet.
Là, ce doit être après la desctruction de l'objet.
Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Comme tous les temporaires qui ne sont pas bindé a une variable reference:
jusqu'a la fin de l'expression.
Oui, et ici, l'expression termine à la fin du constructeur de x( );
Actuellement, je prends une référence sur cet objet,
Si tu la conserve au dela du constructeur de x (comme le laisse croire la
suite), c'est fort possible que ce soit la source de ton probleme (et on ne
se retrouve pas dans le cas general mais vraissemblablement tu appelles le
membre virtuel apres la fin de l'execution du destructeur de Y(1)).
Oui, c'est ça. Ce qui est déstabilisant, c'est que ça fait partie
des trucs qui arrivent 'parfois'. En fait, j'avais fait un exemple
minimal à poster ici, et sur l'exemple, ça plante pas.
Merci.
#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
Marc Boyer writes:j'ai un problème 'pure virtual method called' (avec g++), et je n'arrive
pas à faire d'exemple minimal qui reproduise le pb...
Generalement ca arrive quand on appelle un membre virtuel dans le
constructeur ou le destructeur d'un objet.
Là, ce doit être après la desctruction de l'objet.Mais j'ai peut etre identifié le pb. Quand j'écris un truc du genre
X x( Y(1) );
avec X et Y deux classes, quelle est la durée de vie de l'objet
temporaire Y ?
Comme tous les temporaires qui ne sont pas bindé a une variable reference:
jusqu'a la fin de l'expression.
Oui, et ici, l'expression termine à la fin du constructeur de x( );Actuellement, je prends une référence sur cet objet,
Si tu la conserve au dela du constructeur de x (comme le laisse croire la
suite), c'est fort possible que ce soit la source de ton probleme (et on ne
se retrouve pas dans le cas general mais vraissemblablement tu appelles le
membre virtuel apres la fin de l'execution du destructeur de Y(1)).
Oui, c'est ça. Ce qui est déstabilisant, c'est que ça fait partie
des trucs qui arrivent 'parfois'. En fait, j'avais fait un exemple
minimal à poster ici, et sur l'exemple, ça plante pas.
Merci.
#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
Normalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
Normalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
Normalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le 07-03-2007, Laurent Deniau a écrit :Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
ouiNormalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
ok#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
.clone(), mais j'ai la flemme. C'est du code jetable.public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Le 07-03-2007, Laurent Deniau <laurent.deniau@cern.ch> a écrit :
Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
oui
Normalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
ok
#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
.clone(), mais j'ai la flemme. C'est du code jetable.
public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Le 07-03-2007, Laurent Deniau a écrit :Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
ouiNormalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
ok#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
.clone(), mais j'ai la flemme. C'est du code jetable.public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
ouiNormalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
ok#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
.clone(), mais j'ai la flemme. C'est du code jetable.public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
oui
Normalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
ok
#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
.clone(), mais j'ai la flemme. C'est du code jetable.
public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Probablement parce que ton compilateur ne detruit les temporaires qu'a
la fin du bloc main. Possible que ce soit parce que tu declares f et g
comme des references const dont la semantique a persiste au dela du
constructeur (post-inlining: le bloc du constructeur a ete etendu au
bloc du main). Mais c'est de la cuisine interne au compilateur.
ouiNormalement les temporaires references sans const sont detruits a la fin
de l'expression. Avec le const, la duree de vie est etendue jusqu'a la
fin du bloc.
ok#include <algorithm>
#include <cassert>
struct Fonction {
virtual double operator()(double x) const = 0;
virtual ~Fonction(){};
};
class Affine : public Fonction {
double a;
public:
Affine(double a):a(a){};
double operator()(double x) const {
return a*x;
}
};
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
.clone(), mais j'ai la flemme. C'est du code jetable.public:
Min(const Fonction& f, const Fonction& g):
f(f), g(g){};
double operator()(double x) const {
return std::min( f(x), g(x) );
}
};
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Marc Boyer wrote:class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
ok, j'avais rate ce details.
Non, pas vraiment. Je sais comment produire facilement des 'pure virtual
call' tout seul comme un grand ;-) Et en plus je suis a la bourre pour
mon papier OOPSLA (date de cloture le 19 mars, sic!) donc d'ici la...
Marc Boyer wrote:
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
ok, j'avais rate ce details.
Non, pas vraiment. Je sais comment produire facilement des 'pure virtual
call' tout seul comme un grand ;-) Et en plus je suis a la bourre pour
mon papier OOPSLA (date de cloture le 19 mars, sic!) donc d'ici la...
Marc Boyer wrote:class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
ok, j'avais rate ce details.
Non, pas vraiment. Je sais comment produire facilement des 'pure virtual
call' tout seul comme un grand ;-) Et en plus je suis a la bourre pour
mon papier OOPSLA (date de cloture le 19 mars, sic!) donc d'ici la...
Marc Boyer writes:
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Tu peux le faire ou me l'envoyer en perso. Je ne garanti pas de reponse
rapide.
Marc Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> writes:
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Tu peux le faire ou me l'envoyer en perso. Je ne garanti pas de reponse
rapide.
Marc Boyer writes:
Si le véritable exemple t'intéresse, je peux te le poster.
Ca n'est pas très long (7 classes, 400 lignes, 10ko de code).
Tu peux le faire ou me l'envoyer en perso. Je ne garanti pas de reponse
rapide.
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
..clone(), mais j'ai la flemme. C'est du code jetable.
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
..clone(), mais j'ai la flemme. C'est du code jetable.
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
class Min : public Fonction {
const Fonction& f;
const Fonction& g;
Probleme ici. Il ne faut pas utiliser des references mais des copies.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
..clone(), mais j'ai la flemme. C'est du code jetable.
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
Le problème n'apparaît en effet pas sur cet exemple.
Le vrai problème y est-il lié ? Je ne sais pas. Parfois, il est plus
facile de corriger une erreur que de trouver sa cause exacte. Là,
j'ai remplacé tous mes
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
le polymorphisme existe toujours mais en effet 'Fonction' est virtuel pure.
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
..clone(), mais j'ai la flemme. C'est du code jetable.
des données membre pointeurs sont pourtant la bonne solution, leur
initialisation, utilisation peut selon le nombre d'occurrence être
doublonné avec des refs pour s'épargner qlq déréférencements.
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
à la sortie du constructeur de 'm' les tempos Affine(2) et (3) sont
détruits et le destructeur peut (doit?) réduire sa table de résolution
virtuelle au type de base, m.f et m.g existent toujours et contiennent
les ghosts de ces classes lors de l'appel à m(1), la résolution
virtuelle de () appliquée à f et g tombe alors sur la définition de
Fonction () qui est bien virtuelle pure.
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
normal car les 2 Affine allouées ne sont jamais détruits, les refs (au
sens pointeur commode) f et g de m pointeront toujours sur ces valeurs.
"toujours" est peut être à nuancer, ce point a été discuté dans un fil
pas si vieux sur les références (décrits comme des faux-pointeurs par
"Dieu" et moi-même), ici f et g ont bien un rôle de pointeurs à des
références externes, elles doivent donc ne pas être temporaires.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
le polymorphisme existe toujours mais en effet 'Fonction' est virtuel pure.
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
..clone(), mais j'ai la flemme. C'est du code jetable.
des données membre pointeurs sont pourtant la bonne solution, leur
initialisation, utilisation peut selon le nombre d'occurrence être
doublonné avec des refs pour s'épargner qlq déréférencements.
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
à la sortie du constructeur de 'm' les tempos Affine(2) et (3) sont
détruits et le destructeur peut (doit?) réduire sa table de résolution
virtuelle au type de base, m.f et m.g existent toujours et contiennent
les ghosts de ces classes lors de l'appel à m(1), la résolution
virtuelle de () appliquée à f et g tombe alors sur la définition de
Fonction () qui est bien virtuelle pure.
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
normal car les 2 Affine allouées ne sont jamais détruits, les refs (au
sens pointeur commode) f et g de m pointeront toujours sur ces valeurs.
"toujours" est peut être à nuancer, ce point a été discuté dans un fil
pas si vieux sur les références (décrits comme des faux-pointeurs par
"Dieu" et moi-même), ici f et g ont bien un rôle de pointeurs à des
références externes, elles doivent donc ne pas être temporaires.
Avec des copies
const Fonction f;
je perds le polymorphisme (et sur ce coup, il se plaint que Fonction
a une méthode virtuelle pure).
le polymorphisme existe toujours mais en effet 'Fonction' est virtuel pure.
Alors je pourrais sortir l'artillerie des pointeurs, ou de methode
..clone(), mais j'ai la flemme. C'est du code jetable.
des données membre pointeurs sont pourtant la bonne solution, leur
initialisation, utilisation peut selon le nombre d'occurrence être
doublonné avec des refs pour s'épargner qlq déréférencements.
int main(){
Min m( Affine(2), Affine(3) );
assert( m(1)== 2 );
Min m2( Min(Affine(2), Affine(3)), Affine(4) );
assert( m(1)== 2 );
}
En revanche, je ne vois pas le rapport avec 'pure virtual call' dans cet
exemple.
à la sortie du constructeur de 'm' les tempos Affine(2) et (3) sont
détruits et le destructeur peut (doit?) réduire sa table de résolution
virtuelle au type de base, m.f et m.g existent toujours et contiennent
les ghosts de ces classes lors de l'appel à m(1), la résolution
virtuelle de () appliquée à f et g tombe alors sur la définition de
Fonction () qui est bien virtuelle pure.
Min m( Affine(2), Affine(3) );
par des
Min m( *(new Affine(2)), *(new Affine(3)));
et ça marche.
normal car les 2 Affine allouées ne sont jamais détruits, les refs (au
sens pointeur commode) f et g de m pointeront toujours sur ces valeurs.
"toujours" est peut être à nuancer, ce point a été discuté dans un fil
pas si vieux sur les références (décrits comme des faux-pointeurs par
"Dieu" et moi-même), ici f et g ont bien un rôle de pointeurs à des
références externes, elles doivent donc ne pas être temporaires.