pourquoi ne peut on pas definir un pointeur sur une fonction
constante ?? comme si dessous ?
typedef void (A::*Func) ( void ) const // erreur de compilation
si je definit un pointeur sur une fonction non constante pas
d'erreur de compilation
typedef void (A::*Func)( void ) // compile
du coup si g une classe A
classe A
{
void uneFonctiondeAconst( void ) const;
void uneFonctiondeAnonconst( void );
};
et si j'ai une fonction prenant en parametre "Func"
void mafonction( Func pointer );
alors
mafonction( uneFonctiondeAconst ) // ne compile pas
mafonction( uneFonctiondeAnonconst ) // compile
finalement peut on definit un pointeur sur fonction prenant en
compte aussi bien une fonction const qu'un fonction non const
??
pourquoi ne peut on pas definir un pointeur sur une fonction
constante ?? comme si dessous ?
typedef void (A::*Func) ( void ) const // erreur de compilation
si je definit un pointeur sur une fonction non constante pas
d'erreur de compilation
typedef void (A::*Func)( void ) // compile
du coup si g une classe A
classe A
{
void uneFonctiondeAconst( void ) const;
void uneFonctiondeAnonconst( void );
};
et si j'ai une fonction prenant en parametre "Func"
void mafonction( Func pointer );
alors
mafonction( uneFonctiondeAconst ) // ne compile pas
mafonction( uneFonctiondeAnonconst ) // compile
finalement peut on definit un pointeur sur fonction prenant en
compte aussi bien une fonction const qu'un fonction non const
??
pourquoi ne peut on pas definir un pointeur sur une fonction
constante ?? comme si dessous ?
typedef void (A::*Func) ( void ) const // erreur de compilation
si je definit un pointeur sur une fonction non constante pas
d'erreur de compilation
typedef void (A::*Func)( void ) // compile
du coup si g une classe A
classe A
{
void uneFonctiondeAconst( void ) const;
void uneFonctiondeAnonconst( void );
};
et si j'ai une fonction prenant en parametre "Func"
void mafonction( Func pointer );
alors
mafonction( uneFonctiondeAconst ) // ne compile pas
mafonction( uneFonctiondeAnonconst ) // compile
finalement peut on definit un pointeur sur fonction prenant en
compte aussi bien une fonction const qu'un fonction non const
??
pourquoi ne peut on pas definir un pointeur sur une fonction
constante ?? comme si dessous ?
typedef void (A::*Func) ( void ) const // erreur de compilation
On peut. Où est le problème ? Ça marche très bien chez moi
(g++).
si je definit un pointeur sur une fonction non constante pas
d'erreur de compilation
typedef void (A::*Func)( void ) // compile
Encore, cette ligne est tout à fait légale.
du coup si g une classe A
classe A
{
void uneFonctiondeAconst( void ) const;
void uneFonctiondeAnonconst( void );
};
et si j'ai une fonction prenant en parametre "Func"
void mafonction( Func pointer );
alors
mafonction( uneFonctiondeAconst ) // ne compile pas
mafonction( uneFonctiondeAnonconst ) // compile
finalement peut on definit un pointeur sur fonction prenant en
compte aussi bien une fonction const qu'un fonction non const
??
Je ne suis pas sûr ce que tu essaies de faire. S'il s'agit de
passer l'adresse d'une fonction non const à un pointeur de
fonction const, c'est normal que ça ne marche pas ; c'est une
violation de const. Si en revanche, tu as déclaré un pointeur à
fonction non const, que tu utilises avec un pointeur ou une
référence non const, on pourrait effectivement s'attendre à ce
qu'un pointeur à une fonction const marche. Or qu'il n'y a pas
de conversion implicite ; en fait, la seule conversion qui
marche, c'est un reinterpret_cast.
Mais le problème n'est pas propre aux fonctions membres (et
pointeurs à des fonctions membres). Considère le suivant :
void f( int* ) ;
void g( int const* ) ;
typedef void (*Pf)( int* ) ;
void
h()
{
Pf p ;
p = f ; // Bon...
p = g ; // Mauvais...
}
Si tu considères l'adresse de l'objet passé au this d'une
fonction membre comme un paramètre supplémentaire, ton problème
n'est qu'une manifestation particulière du problème ci-dessus
(qui existe déjà en C).
A priori, on pourrait bien permettre ces conversions implicites,
aussi bien en C qu'en C++. Si on ne le fait pas, j'imagine que
c'est parce qu'on n'a pas considéré les pointeurs à des
fonctions un type aussi important pour vouloir consacrer le
temps et l'effort nécessaire pour bien spécifier quelles
conversions sont légales, et quelles non. (Le bien spécifier est
loin d'être trivial.) On s'est contenté à ne pas supporter des
conversions implicites du tout, et de laisser aux programmeur de
faire une conversion explicite le cas où. Malheureusement, en
C++, cette conversion devient un reinterpret_cast, ce qui envoie
bien le mauvais message.
--
James Kanze GABI Software
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
pourquoi ne peut on pas definir un pointeur sur une fonction
constante ?? comme si dessous ?
typedef void (A::*Func) ( void ) const // erreur de compilation
On peut. Où est le problème ? Ça marche très bien chez moi
(g++).
si je definit un pointeur sur une fonction non constante pas
d'erreur de compilation
typedef void (A::*Func)( void ) // compile
Encore, cette ligne est tout à fait légale.
du coup si g une classe A
classe A
{
void uneFonctiondeAconst( void ) const;
void uneFonctiondeAnonconst( void );
};
et si j'ai une fonction prenant en parametre "Func"
void mafonction( Func pointer );
alors
mafonction( uneFonctiondeAconst ) // ne compile pas
mafonction( uneFonctiondeAnonconst ) // compile
finalement peut on definit un pointeur sur fonction prenant en
compte aussi bien une fonction const qu'un fonction non const
??
Je ne suis pas sûr ce que tu essaies de faire. S'il s'agit de
passer l'adresse d'une fonction non const à un pointeur de
fonction const, c'est normal que ça ne marche pas ; c'est une
violation de const. Si en revanche, tu as déclaré un pointeur à
fonction non const, que tu utilises avec un pointeur ou une
référence non const, on pourrait effectivement s'attendre à ce
qu'un pointeur à une fonction const marche. Or qu'il n'y a pas
de conversion implicite ; en fait, la seule conversion qui
marche, c'est un reinterpret_cast.
Mais le problème n'est pas propre aux fonctions membres (et
pointeurs à des fonctions membres). Considère le suivant :
void f( int* ) ;
void g( int const* ) ;
typedef void (*Pf)( int* ) ;
void
h()
{
Pf p ;
p = f ; // Bon...
p = g ; // Mauvais...
}
Si tu considères l'adresse de l'objet passé au this d'une
fonction membre comme un paramètre supplémentaire, ton problème
n'est qu'une manifestation particulière du problème ci-dessus
(qui existe déjà en C).
A priori, on pourrait bien permettre ces conversions implicites,
aussi bien en C qu'en C++. Si on ne le fait pas, j'imagine que
c'est parce qu'on n'a pas considéré les pointeurs à des
fonctions un type aussi important pour vouloir consacrer le
temps et l'effort nécessaire pour bien spécifier quelles
conversions sont légales, et quelles non. (Le bien spécifier est
loin d'être trivial.) On s'est contenté à ne pas supporter des
conversions implicites du tout, et de laisser aux programmeur de
faire une conversion explicite le cas où. Malheureusement, en
C++, cette conversion devient un reinterpret_cast, ce qui envoie
bien le mauvais message.
--
James Kanze GABI Software
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
pourquoi ne peut on pas definir un pointeur sur une fonction
constante ?? comme si dessous ?
typedef void (A::*Func) ( void ) const // erreur de compilation
On peut. Où est le problème ? Ça marche très bien chez moi
(g++).
si je definit un pointeur sur une fonction non constante pas
d'erreur de compilation
typedef void (A::*Func)( void ) // compile
Encore, cette ligne est tout à fait légale.
du coup si g une classe A
classe A
{
void uneFonctiondeAconst( void ) const;
void uneFonctiondeAnonconst( void );
};
et si j'ai une fonction prenant en parametre "Func"
void mafonction( Func pointer );
alors
mafonction( uneFonctiondeAconst ) // ne compile pas
mafonction( uneFonctiondeAnonconst ) // compile
finalement peut on definit un pointeur sur fonction prenant en
compte aussi bien une fonction const qu'un fonction non const
??
Je ne suis pas sûr ce que tu essaies de faire. S'il s'agit de
passer l'adresse d'une fonction non const à un pointeur de
fonction const, c'est normal que ça ne marche pas ; c'est une
violation de const. Si en revanche, tu as déclaré un pointeur à
fonction non const, que tu utilises avec un pointeur ou une
référence non const, on pourrait effectivement s'attendre à ce
qu'un pointeur à une fonction const marche. Or qu'il n'y a pas
de conversion implicite ; en fait, la seule conversion qui
marche, c'est un reinterpret_cast.
Mais le problème n'est pas propre aux fonctions membres (et
pointeurs à des fonctions membres). Considère le suivant :
void f( int* ) ;
void g( int const* ) ;
typedef void (*Pf)( int* ) ;
void
h()
{
Pf p ;
p = f ; // Bon...
p = g ; // Mauvais...
}
Si tu considères l'adresse de l'objet passé au this d'une
fonction membre comme un paramètre supplémentaire, ton problème
n'est qu'une manifestation particulière du problème ci-dessus
(qui existe déjà en C).
A priori, on pourrait bien permettre ces conversions implicites,
aussi bien en C qu'en C++. Si on ne le fait pas, j'imagine que
c'est parce qu'on n'a pas considéré les pointeurs à des
fonctions un type aussi important pour vouloir consacrer le
temps et l'effort nécessaire pour bien spécifier quelles
conversions sont légales, et quelles non. (Le bien spécifier est
loin d'être trivial.) On s'est contenté à ne pas supporter des
conversions implicites du tout, et de laisser aux programmeur de
faire une conversion explicite le cas où. Malheureusement, en
C++, cette conversion devient un reinterpret_cast, ce qui envoie
bien le mauvais message.
--
James Kanze GABI Software
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
a écrit dans le message de news:
Geoffrey wrote:Je ne suis pas sûr ce que tu essaies de faire. S'il s'agit
de passer l'adresse d'une fonction non const à un pointeur
de fonction const, c'est normal que ça ne marche pas ; c'est
une violation de const. Si en revanche, tu as déclaré un
pointeur à fonction non const, que tu utilises avec un
pointeur ou une référence non const, on pourrait
effectivement s'attendre à ce qu'un pointeur à une fonction
const marche. Or qu'il n'y a pas de conversion implicite ;
en fait, la seule conversion qui marche, c'est un
reinterpret_cast.
En fait j'ai declare un pointeur sur une fonction non const,
et j'essaye de lui passer un pointeur vers une fonction const.
Effectivement, je me heurtait a un probleme de type ... le
reinterpret_cast autorise la compilation on verra a
l'execution si ca n'explose pas ensuite :))
Maintenant si j'etend un peu mon probleme :
Si j'ai :
classe A
{
public:
typedef bool (*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A
{
bool fonctB(void);
}
si quelque part dans B je veux ecrire fonctA( &B::FonctB );
J'obtient normalement une erreur de compilation car on ne pas
convertir de bool (B::*) () vers bool ( * )()
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
mais franchement je ne suis pas sur de la solution ...
<kanze@gabi-soft.fr> a écrit dans le message de news:
1125473889.263721.200310@z14g2000cwz.googlegroups.com...
Geoffrey wrote:
Je ne suis pas sûr ce que tu essaies de faire. S'il s'agit
de passer l'adresse d'une fonction non const à un pointeur
de fonction const, c'est normal que ça ne marche pas ; c'est
une violation de const. Si en revanche, tu as déclaré un
pointeur à fonction non const, que tu utilises avec un
pointeur ou une référence non const, on pourrait
effectivement s'attendre à ce qu'un pointeur à une fonction
const marche. Or qu'il n'y a pas de conversion implicite ;
en fait, la seule conversion qui marche, c'est un
reinterpret_cast.
En fait j'ai declare un pointeur sur une fonction non const,
et j'essaye de lui passer un pointeur vers une fonction const.
Effectivement, je me heurtait a un probleme de type ... le
reinterpret_cast autorise la compilation on verra a
l'execution si ca n'explose pas ensuite :))
Maintenant si j'etend un peu mon probleme :
Si j'ai :
classe A
{
public:
typedef bool (*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A
{
bool fonctB(void);
}
si quelque part dans B je veux ecrire fonctA( &B::FonctB );
J'obtient normalement une erreur de compilation car on ne pas
convertir de bool (B::*) () vers bool ( * )()
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
mais franchement je ne suis pas sur de la solution ...
a écrit dans le message de news:
Geoffrey wrote:Je ne suis pas sûr ce que tu essaies de faire. S'il s'agit
de passer l'adresse d'une fonction non const à un pointeur
de fonction const, c'est normal que ça ne marche pas ; c'est
une violation de const. Si en revanche, tu as déclaré un
pointeur à fonction non const, que tu utilises avec un
pointeur ou une référence non const, on pourrait
effectivement s'attendre à ce qu'un pointeur à une fonction
const marche. Or qu'il n'y a pas de conversion implicite ;
en fait, la seule conversion qui marche, c'est un
reinterpret_cast.
En fait j'ai declare un pointeur sur une fonction non const,
et j'essaye de lui passer un pointeur vers une fonction const.
Effectivement, je me heurtait a un probleme de type ... le
reinterpret_cast autorise la compilation on verra a
l'execution si ca n'explose pas ensuite :))
Maintenant si j'etend un peu mon probleme :
Si j'ai :
classe A
{
public:
typedef bool (*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A
{
bool fonctB(void);
}
si quelque part dans B je veux ecrire fonctA( &B::FonctB );
J'obtient normalement une erreur de compilation car on ne pas
convertir de bool (B::*) () vers bool ( * )()
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
mais franchement je ne suis pas sur de la solution ...
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
Et qu'est-ce que functA fait avec ce pointeur ? Il faut bien
qu'il ait un pointeur à un objet de type B pour l'utiliser ; son
this ne suffit pas.
mais franchement je ne suis pas sur de la solution ...
Prèsque toujours quand j'ai commencé avec des pointeurs à des
fonctions membres, j'ai fini par les convertir en objets
fonctionnels avec un operator()() virtuel. Donc, dans ton cas :
class A
{
public:
struct AbstractCB
{
virtual ~AbstractCB() {}
virtual bool operator()() const = 0 ;
} ;
void fonctA( AbstractCB const& f ) ;
// ...
} ;
template< typename D >
class CB : public AbstractCB
{
public :
CB( D* obj, bool (D::*pfm)() )
: myObj( obj )
, myPfm( pfm )
{
}
virtual bool operator()() const
{
return (myObj->*myPfm)() ;
}
private:
D* myObj ;
bool (D::* myPfm)() ;
} ;
(Sauf que souvent, le pointeur à la fonction membre peut aussi
être paramètre du template.)
Ensuite, tu crées le CB<D> qu'il te faut, comme variable locale,
voire même comme temporaire.
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
Et qu'est-ce que functA fait avec ce pointeur ? Il faut bien
qu'il ait un pointeur à un objet de type B pour l'utiliser ; son
this ne suffit pas.
mais franchement je ne suis pas sur de la solution ...
Prèsque toujours quand j'ai commencé avec des pointeurs à des
fonctions membres, j'ai fini par les convertir en objets
fonctionnels avec un operator()() virtuel. Donc, dans ton cas :
class A
{
public:
struct AbstractCB
{
virtual ~AbstractCB() {}
virtual bool operator()() const = 0 ;
} ;
void fonctA( AbstractCB const& f ) ;
// ...
} ;
template< typename D >
class CB : public AbstractCB
{
public :
CB( D* obj, bool (D::*pfm)() )
: myObj( obj )
, myPfm( pfm )
{
}
virtual bool operator()() const
{
return (myObj->*myPfm)() ;
}
private:
D* myObj ;
bool (D::* myPfm)() ;
} ;
(Sauf que souvent, le pointeur à la fonction membre peut aussi
être paramètre du template.)
Ensuite, tu crées le CB<D> qu'il te faut, comme variable locale,
voire même comme temporaire.
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
Et qu'est-ce que functA fait avec ce pointeur ? Il faut bien
qu'il ait un pointeur à un objet de type B pour l'utiliser ; son
this ne suffit pas.
mais franchement je ne suis pas sur de la solution ...
Prèsque toujours quand j'ai commencé avec des pointeurs à des
fonctions membres, j'ai fini par les convertir en objets
fonctionnels avec un operator()() virtuel. Donc, dans ton cas :
class A
{
public:
struct AbstractCB
{
virtual ~AbstractCB() {}
virtual bool operator()() const = 0 ;
} ;
void fonctA( AbstractCB const& f ) ;
// ...
} ;
template< typename D >
class CB : public AbstractCB
{
public :
CB( D* obj, bool (D::*pfm)() )
: myObj( obj )
, myPfm( pfm )
{
}
virtual bool operator()() const
{
return (myObj->*myPfm)() ;
}
private:
D* myObj ;
bool (D::* myPfm)() ;
} ;
(Sauf que souvent, le pointeur à la fonction membre peut aussi
être paramètre du template.)
Ensuite, tu crées le CB<D> qu'il te faut, comme variable locale,
voire même comme temporaire.
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
Et qu'est-ce que functA fait avec ce pointeur ? Il faut bien
qu'il ait un pointeur à un objet de type B pour l'utiliser ;
son this ne suffit pas.
En fait je vais serializer des object C++ en XML ( et
inversement ) et plutot que de faire une solution bete et
jetable, je me demandais si je pouvais pas generaliser la
serialisation C++ <-> XML. J'ai donc une classe de base qui a
pour membre des tableau de pointeur sur fonction definissant
pour chaque balise une fonction set et une fonction get de la
valeur a stocker.
Ainsi dans la classe derivé, je n'ai plus qu'a renseigner ce
tableau pour que le stockage et destockage de la valeur soit
automitique ( y'a surement mieux comme solution )
mais franchement je ne suis pas sur de la solution ...
Prèsque toujours quand j'ai commencé avec des pointeurs à des
fonctions membres, j'ai fini par les convertir en objets
fonctionnels avec un operator()() virtuel. Donc, dans ton
cas :
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
Et qu'est-ce que functA fait avec ce pointeur ? Il faut bien
qu'il ait un pointeur à un objet de type B pour l'utiliser ;
son this ne suffit pas.
En fait je vais serializer des object C++ en XML ( et
inversement ) et plutot que de faire une solution bete et
jetable, je me demandais si je pouvais pas generaliser la
serialisation C++ <-> XML. J'ai donc une classe de base qui a
pour membre des tableau de pointeur sur fonction definissant
pour chaque balise une fonction set et une fonction get de la
valeur a stocker.
Ainsi dans la classe derivé, je n'ai plus qu'a renseigner ce
tableau pour que le stockage et destockage de la valeur soit
automitique ( y'a surement mieux comme solution )
mais franchement je ne suis pas sur de la solution ...
Prèsque toujours quand j'ai commencé avec des pointeurs à des
fonctions membres, j'ai fini par les convertir en objets
fonctionnels avec un operator()() virtuel. Donc, dans ton
cas :
La solution que j'ai mis en place pour ca est de transformer A
en classe template
template< class X>
classe A
{
public:
typedef bool (X::*FunctPtr) ( void );
fonctA ( FunctPtr _pointer );
}
classe B : public A<B>
{
bool fonctB(void);
}
maintenant je peux ecrire fonctA( &B::FonctB );
Et qu'est-ce que functA fait avec ce pointeur ? Il faut bien
qu'il ait un pointeur à un objet de type B pour l'utiliser ;
son this ne suffit pas.
En fait je vais serializer des object C++ en XML ( et
inversement ) et plutot que de faire une solution bete et
jetable, je me demandais si je pouvais pas generaliser la
serialisation C++ <-> XML. J'ai donc une classe de base qui a
pour membre des tableau de pointeur sur fonction definissant
pour chaque balise une fonction set et une fonction get de la
valeur a stocker.
Ainsi dans la classe derivé, je n'ai plus qu'a renseigner ce
tableau pour que le stockage et destockage de la valeur soit
automitique ( y'a surement mieux comme solution )
mais franchement je ne suis pas sur de la solution ...
Prèsque toujours quand j'ai commencé avec des pointeurs à des
fonctions membres, j'ai fini par les convertir en objets
fonctionnels avec un operator()() virtuel. Donc, dans ton
cas :