Si j'ai bien compris tu veux déclarer un pointeur de fonction membre static.
En fait un pointeur de fonction membre static est de la même forme qu'un pointeur de fonction, il n'a pas besoin de connaitre le type de l'objet auquel la fonction appartient.
ex: #include <cstdlib> #include <iostream>
using namespace std;
class C{ public: static void fonction(); }
void C::fonction(){ cout<<"fonction"<<endl; }
int main(){ void (*p_fonction)() = C::fonction; p_fonction(); return EXIT_SUCCESS; }
Si j'ai bien compris tu veux déclarer un pointeur de fonction membre static.
En fait un pointeur de fonction membre static est de la même forme qu'un
pointeur de fonction, il n'a pas besoin de connaitre le type de l'objet
auquel la fonction appartient.
ex:
#include <cstdlib>
#include <iostream>
using namespace std;
class C{
public:
static void fonction();
}
void C::fonction(){
cout<<"fonction"<<endl;
}
int main(){
void (*p_fonction)() = C::fonction;
p_fonction();
return EXIT_SUCCESS;
}
Si j'ai bien compris tu veux déclarer un pointeur de fonction membre static.
En fait un pointeur de fonction membre static est de la même forme qu'un pointeur de fonction, il n'a pas besoin de connaitre le type de l'objet auquel la fonction appartient.
ex: #include <cstdlib> #include <iostream>
using namespace std;
class C{ public: static void fonction(); }
void C::fonction(){ cout<<"fonction"<<endl; }
int main(){ void (*p_fonction)() = C::fonction; p_fonction(); return EXIT_SUCCESS; }
Sylvain
Bruno Causse wrote on 13/06/2006 23:05:
bonsoir, je n'arrive pas a resoudre mon prob
/* static */
static bool check_A1(const int data); static bool check_A2(const int data); static bool check_A3(const int data);
quel avantage par rapport à
bool check_A1(const int data); bool check_A2(const int data); bool check_A3(const int data);
si vous pensez en C, codez en C. (ceci n'insinue aucune hiérarchie C vs C++)
/* comment declarer le tableau de pointeur de fonction membre static */
pourquoi déclarer le tableau de pointeur de fonction comme données membre statique ??
static bool (MaClass::*check[64])(const int discs_player); // ?????????
/*comment appeler une fonction de MaClass::check[] */ if((*(Maclass::check[p]))(discs[player])) { // ???????? } }
en C++ ?
si le traitement étant différant par la nature de l'objet traité, en définissant:
class Medium { virtual bool check(const int) = 0; };
class Disc : public Medium { bool check(const int data){ // ce qui était mis dans check_A1 } };
ici vous semblez juste avoir besoin de savoir si un disc vérifie le critère p; sortez les functions check de MaClass (cela ne la concerne pas) et mettez ces fonctions dans un classe Disc avec une interface permettant de demander à un disc (discs[player]) s'il vérifie 'p' ou directement quelles conditions il vérifie (unique ou énumérées).
Sylvain.
Sylvain.
Bruno Causse wrote on 13/06/2006 23:05:
bonsoir, je n'arrive pas a resoudre mon prob
/* static */
static bool check_A1(const int data);
static bool check_A2(const int data);
static bool check_A3(const int data);
quel avantage par rapport à
bool check_A1(const int data);
bool check_A2(const int data);
bool check_A3(const int data);
si vous pensez en C, codez en C.
(ceci n'insinue aucune hiérarchie C vs C++)
/* comment declarer le tableau de pointeur de fonction membre static */
pourquoi déclarer le tableau de pointeur de fonction comme données
membre statique ??
static bool (MaClass::*check[64])(const int discs_player); // ?????????
/*comment appeler une fonction de MaClass::check[] */
if((*(Maclass::check[p]))(discs[player])) { // ????????
}
}
en C++ ?
si le traitement étant différant par la nature de l'objet traité, en
définissant:
class Medium {
virtual bool check(const int) = 0;
};
class Disc : public Medium {
bool check(const int data){
// ce qui était mis dans check_A1
}
};
ici vous semblez juste avoir besoin de savoir si un disc vérifie le
critère p; sortez les functions check de MaClass (cela ne la concerne
pas) et mettez ces fonctions dans un classe Disc avec une interface
permettant de demander à un disc (discs[player]) s'il vérifie 'p' ou
directement quelles conditions il vérifie (unique ou énumérées).
/*comment appeler une fonction de MaClass::check[] */ if((*(Maclass::check[p]))(discs[player])) { // ???????? } }
en C++ ?
si le traitement étant différant par la nature de l'objet traité, en définissant:
class Medium { virtual bool check(const int) = 0; };
class Disc : public Medium { bool check(const int data){ // ce qui était mis dans check_A1 } };
ici vous semblez juste avoir besoin de savoir si un disc vérifie le critère p; sortez les functions check de MaClass (cela ne la concerne pas) et mettez ces fonctions dans un classe Disc avec une interface permettant de demander à un disc (discs[player]) s'il vérifie 'p' ou directement quelles conditions il vérifie (unique ou énumérées).
Sylvain.
Sylvain.
kanze
Sylvain wrote:
Bruno Causse wrote on 13/06/2006 23:05:
bonsoir, je n'arrive pas a resoudre mon prob
/* static */
static bool check_A1(const int data); static bool check_A2(const int data); static bool check_A3(const int data);
quel avantage par rapport à
bool check_A1(const int data); bool check_A2(const int data); bool check_A3(const int data);
Ce sont deux choses différentes. Il n'y a pas d'« avantage », l'un par rapport à l'autre : on utilise celui qui a la sémantique qui correspond au problème.
si vous pensez en C, codez en C. (ceci n'insinue aucune hiérarchie C vs C++)
Quel rapport avec C -- il s'agit dans les deux cas des fonctions membre.
/* comment declarer le tableau de pointeur de fonction membre static */
pourquoi déclarer le tableau de pointeur de fonction comme données membre statique ??
Parce que c'est ce qu'il lui faut dans l'application ? Vue qu'il ne nous a pas dit ce qu'il essaie de faire (au niveau abstrait), on ne peut pas juger si c'est la bonne solution ou non.
-- 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
Sylvain wrote:
Bruno Causse wrote on 13/06/2006 23:05:
bonsoir, je n'arrive pas a resoudre mon prob
/* static */
static bool check_A1(const int data);
static bool check_A2(const int data);
static bool check_A3(const int data);
quel avantage par rapport à
bool check_A1(const int data);
bool check_A2(const int data);
bool check_A3(const int data);
Ce sont deux choses différentes. Il n'y a pas d'« avantage »,
l'un par rapport à l'autre : on utilise celui qui a la
sémantique qui correspond au problème.
si vous pensez en C, codez en C.
(ceci n'insinue aucune hiérarchie C vs C++)
Quel rapport avec C -- il s'agit dans les deux cas des fonctions
membre.
/* comment declarer le tableau de pointeur de fonction
membre static */
pourquoi déclarer le tableau de pointeur de fonction comme
données membre statique ??
Parce que c'est ce qu'il lui faut dans l'application ? Vue
qu'il ne nous a pas dit ce qu'il essaie de faire (au niveau
abstrait), on ne peut pas juger si c'est la bonne solution ou
non.
--
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
static bool check_A1(const int data); static bool check_A2(const int data); static bool check_A3(const int data);
quel avantage par rapport à
bool check_A1(const int data); bool check_A2(const int data); bool check_A3(const int data);
Ce sont deux choses différentes. Il n'y a pas d'« avantage », l'un par rapport à l'autre : on utilise celui qui a la sémantique qui correspond au problème.
si vous pensez en C, codez en C. (ceci n'insinue aucune hiérarchie C vs C++)
Quel rapport avec C -- il s'agit dans les deux cas des fonctions membre.
/* comment declarer le tableau de pointeur de fonction membre static */
pourquoi déclarer le tableau de pointeur de fonction comme données membre statique ??
Parce que c'est ce qu'il lui faut dans l'application ? Vue qu'il ne nous a pas dit ce qu'il essaie de faire (au niveau abstrait), on ne peut pas juger si c'est la bonne solution ou non.
-- 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
kanze
Bruno Causse wrote:
bonsoir, je n'arrive pas a resoudre mon prob
/* pseudo code */
class MaClass {
/* static */
static bool check_A1(const int data); static bool check_A2(const int data); static bool check_A3(const int data);
static init_check();
/* comment declarer le tableau de pointeur de fonction membre static */
static bool (MaClass::*check[64])(const int discs_player); // ?????????
Le type d'une fonction membre statique, c'est le même que le type d'une fonction non-membre. Si « check » doit contenir des pointeurs à des fonctions membre statique, il faut le déclarer :
static bool (*check[64])( int discs_player ) ;
Note aussi que puisque ce n'est qu'une déclaration ici, la dimension est facultative.
/* membre */
int discs[10]; int player;
bool uneMethode(); }
bool MaClass::check_A1(const int data) { .../...} bool MaClass::check_A2(const int data) { .../...} bool MaClass::check_A3(const int data) { .../...}
(Si c'est const, évidemment, l'initialisation dans une fonction est interdite. Il faut l'initialiser dans la définition, comme ici.)
bool MaClass::uneMethode(int p) {
.../... /*comment appeler une fonction de MaClass::check[] */ if((*(Maclass::check[p]))(discs[player])) { // ????????
S'il s'agit bien des fonctions statiques :
if ( (*check[ p ])( discs[ player ] ) ) {
Si les fonctions ne sont pas statiques (et le type du tableau est des pointeurs aux fonctions membres), il faut utiliser l'opérateur .* ou ->*, ce qui implique un objet ou un pointeur explicit ; le this implicite ne vaut plus. On écrirait alors :
if ( (this->*(check[ p ]))( discs[ player ] ) ) {
(Je ne crois pas que les (...) autour de check[p] soit nécessaire. Mais je préfère les mettre ; je ne suis pas toujours 100% sûr des précédances des opérateurs si peu utilisés.)
-- 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
Bruno Causse wrote:
bonsoir, je n'arrive pas a resoudre mon prob
/* pseudo code */
class MaClass {
/* static */
static bool check_A1(const int data);
static bool check_A2(const int data);
static bool check_A3(const int data);
static init_check();
/* comment declarer le tableau de pointeur de fonction membre static */
static bool (MaClass::*check[64])(const int discs_player); // ?????????
Le type d'une fonction membre statique, c'est le même que le
type d'une fonction non-membre. Si « check » doit contenir des
pointeurs à des fonctions membre statique, il faut le déclarer :
static bool (*check[64])( int discs_player ) ;
Note aussi que puisque ce n'est qu'une déclaration ici, la
dimension est facultative.
/* membre */
int discs[10];
int player;
bool uneMethode();
}
bool MaClass::check_A1(const int data) { .../...}
bool MaClass::check_A2(const int data) { .../...}
bool MaClass::check_A3(const int data) { .../...}
(Si c'est const, évidemment, l'initialisation dans une fonction
est interdite. Il faut l'initialiser dans la définition, comme
ici.)
bool MaClass::uneMethode(int p) {
.../...
/*comment appeler une fonction de MaClass::check[] */
if((*(Maclass::check[p]))(discs[player])) { // ????????
S'il s'agit bien des fonctions statiques :
if ( (*check[ p ])( discs[ player ] ) ) {
Si les fonctions ne sont pas statiques (et le type du tableau
est des pointeurs aux fonctions membres), il faut utiliser
l'opérateur .* ou ->*, ce qui implique un objet ou un pointeur
explicit ; le this implicite ne vaut plus. On écrirait alors :
if ( (this->*(check[ p ]))( discs[ player ] ) ) {
(Je ne crois pas que les (...) autour de check[p] soit
nécessaire. Mais je préfère les mettre ; je ne suis pas toujours
100% sûr des précédances des opérateurs si peu utilisés.)
--
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
static bool check_A1(const int data); static bool check_A2(const int data); static bool check_A3(const int data);
static init_check();
/* comment declarer le tableau de pointeur de fonction membre static */
static bool (MaClass::*check[64])(const int discs_player); // ?????????
Le type d'une fonction membre statique, c'est le même que le type d'une fonction non-membre. Si « check » doit contenir des pointeurs à des fonctions membre statique, il faut le déclarer :
static bool (*check[64])( int discs_player ) ;
Note aussi que puisque ce n'est qu'une déclaration ici, la dimension est facultative.
/* membre */
int discs[10]; int player;
bool uneMethode(); }
bool MaClass::check_A1(const int data) { .../...} bool MaClass::check_A2(const int data) { .../...} bool MaClass::check_A3(const int data) { .../...}
(Si c'est const, évidemment, l'initialisation dans une fonction est interdite. Il faut l'initialiser dans la définition, comme ici.)
bool MaClass::uneMethode(int p) {
.../... /*comment appeler une fonction de MaClass::check[] */ if((*(Maclass::check[p]))(discs[player])) { // ????????
S'il s'agit bien des fonctions statiques :
if ( (*check[ p ])( discs[ player ] ) ) {
Si les fonctions ne sont pas statiques (et le type du tableau est des pointeurs aux fonctions membres), il faut utiliser l'opérateur .* ou ->*, ce qui implique un objet ou un pointeur explicit ; le this implicite ne vaut plus. On écrirait alors :
if ( (this->*(check[ p ]))( discs[ player ] ) ) {
(Je ne crois pas que les (...) autour de check[p] soit nécessaire. Mais je préfère les mettre ; je ne suis pas toujours 100% sûr des précédances des opérateurs si peu utilisés.)
-- 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
Sylvain
kanze wrote on 14/06/2006 10:32:
quel avantage par rapport à
Ce sont deux choses différentes. Il n'y a pas d'« avantage », l'un par rapport à l'autre : on utilise celui qui a la sémantique qui correspond au problème.
tu ne commentes pas ce que j'ai écrit, donc ...
si vous pensez en C, codez en C. (ceci n'insinue aucune hiérarchie C vs C++)
Quel rapport avec C -- il s'agit dans les deux cas des fonctions membre.
où as-tu vu un "class/struct QlqChose" devant mes "bool check_Ai" ??
/* comment declarer le tableau de pointeur de fonction membre static */
pourquoi déclarer le tableau de pointeur de fonction comme données membre statique ??
Parce que c'est ce qu'il lui faut dans l'application ? Vue qu'il ne nous a pas dit ce qu'il essaie de faire (au niveau abstrait), on ne peut pas juger si c'est la bonne solution ou non.
où ai-je porté un jegement ?
Sylvain.
kanze wrote on 14/06/2006 10:32:
quel avantage par rapport à
Ce sont deux choses différentes. Il n'y a pas d'« avantage »,
l'un par rapport à l'autre : on utilise celui qui a la
sémantique qui correspond au problème.
tu ne commentes pas ce que j'ai écrit, donc ...
si vous pensez en C, codez en C.
(ceci n'insinue aucune hiérarchie C vs C++)
Quel rapport avec C -- il s'agit dans les deux cas des fonctions
membre.
où as-tu vu un "class/struct QlqChose" devant mes "bool check_Ai" ??
/* comment declarer le tableau de pointeur de fonction
membre static */
pourquoi déclarer le tableau de pointeur de fonction comme
données membre statique ??
Parce que c'est ce qu'il lui faut dans l'application ? Vue
qu'il ne nous a pas dit ce qu'il essaie de faire (au niveau
abstrait), on ne peut pas juger si c'est la bonne solution ou
non.
Ce sont deux choses différentes. Il n'y a pas d'« avantage », l'un par rapport à l'autre : on utilise celui qui a la sémantique qui correspond au problème.
tu ne commentes pas ce que j'ai écrit, donc ...
si vous pensez en C, codez en C. (ceci n'insinue aucune hiérarchie C vs C++)
Quel rapport avec C -- il s'agit dans les deux cas des fonctions membre.
où as-tu vu un "class/struct QlqChose" devant mes "bool check_Ai" ??
/* comment declarer le tableau de pointeur de fonction membre static */
pourquoi déclarer le tableau de pointeur de fonction comme données membre statique ??
Parce que c'est ce qu'il lui faut dans l'application ? Vue qu'il ne nous a pas dit ce qu'il essaie de faire (au niveau abstrait), on ne peut pas juger si c'est la bonne solution ou non.
où ai-je porté un jegement ?
Sylvain.
Bruno CAUSSE
dans l'article , kanze à a écrit le 14/06/06 10:45 :
[...]
Merci maintenant ca fonctionne :-)
Mais c'est loin d'etre evident pour le simple boetien que je suis.
J'ai meme eu du mal a comprendre pourquoi entre ta solution et celle de fabien il manquait les * et & , oui :-) a cause du typedef.
Mais plein de choses m'echappent, par ex:
Utilisation a l'interieur d'une methode membre
((this)->*(function[id]))(param)
Et dans une methode d'une autre classe
((objet)->*(objet.function[id]))(param) pourquoi le 2e "objet"?
dans l'article 1150274706.189638.78370@p79g2000cwp.googlegroups.com, kanze à
kanze@gabi-soft.fr a écrit le 14/06/06 10:45 :
[...]
Merci maintenant ca fonctionne :-)
Mais c'est loin d'etre evident pour le simple boetien que je suis.
J'ai meme eu du mal a comprendre pourquoi entre ta solution et celle de
fabien il manquait les * et & , oui :-) a cause du typedef.
Mais plein de choses m'echappent, par ex:
Utilisation a l'interieur d'une methode membre
((this)->*(function[id]))(param)
Et dans une methode d'une autre classe
((objet)->*(objet.function[id]))(param) pourquoi le 2e "objet"?
dans l'article , kanze à a écrit le 14/06/06 10:45 :
[...]
Merci maintenant ca fonctionne :-)
Mais c'est loin d'etre evident pour le simple boetien que je suis.
J'ai meme eu du mal a comprendre pourquoi entre ta solution et celle de fabien il manquait les * et & , oui :-) a cause du typedef.
Mais plein de choses m'echappent, par ex:
Utilisation a l'interieur d'une methode membre
((this)->*(function[id]))(param)
Et dans une methode d'une autre classe
((objet)->*(objet.function[id]))(param) pourquoi le 2e "objet"?
kanze
Bruno CAUSSE wrote:
dans l'article , kanz e à a écrit le 14/06/06 10:45 :
[...]
Merci maintenant ca fonctionne :-)
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Le C++ est un langage assez complexe, qui exige un certain apprentissage. Et une attention assez poussée aux détails : des distinctions du genre déclaration / définition ou initialisation / affectation sont parfois d'une grande importance, même si la distinction n'est pas toujours claire pour un débuttant.
J'ai meme eu du mal a comprendre pourquoi entre ta solution et celle de fabien il manquait les * et & , oui :-) a cause du typedef.
Non seulement. Lors de l'utilisation, il y a des conversions implicites, etc., qui fait que certains opérateurs sont parfois facultatifs. Moi, je les mets quand même, en général, parce que je trouve que ça rend plus clair ce qu'on fait, mais d'autres les laissent systèmatiquement. Donc :
extern int f() ; int (*pf)() ; // C'est un pointeur à une fonction... pf = &f ; // On l'initialise avec l'adresse de f. pf = f ; // Aussi. Il y a conversion implicite.
(*pf)() ; // On appelle la fonction... pf() ; // Aussi... on peut se servir d'un // pointeur à une fonction exactement // comme le nom d'une fonction.
En gros, pour des raisons historiques, on peut utiliser le nom d'une fonction et son adresse de façon interchangeable ; le compilateur comprend d'après le contexte ce qu'il faut, et fait les conversions nécessaire. Personellement, je choisis d'être explicit quand même, mais il y a une grande tradition qui fait le contraire, et il y a même certains idiomes (avec les templates) qui y compte.
Mais plein de choses m'echappent, par ex:
Utilisation a l'interieur d'une methode membre
((this)->*(function[id]))(param)
Attention : il s'agit ici de l'utilisaton d'un pointeur à fonction membre (non-statique). La syntaxe autour des pointeurs à membre est assez complex ; à ta place, j'attendrais avoir maîtriser des bases avant de s'y venturer, d'autant plus que ce n'est pas souvent utile, et jamais nécessaire. J'aborderais même les templates avant -- non qu'ils soient moins complexe, mais ils sont de beaucoup plus utiles.
Et dans une methode d'une autre classe
((objet)->*(objet.function[id]))(param) pourquoi le 2e "objet"?
Parce que fonction est un membre (non-statique). Sans l'« objet », c'est implicitement comme si on avait écrit « this->function » ; c-à-d qu'on accederait au tableau membre de cet objet, et non à celui de l'objet « objet ». (En revanche, l'expression telle que tu l'as réproduit ci-dessus ne peut pas être légal. Si « objet » est un pointeur, « objet.function » ne passe pas, parce que l'opérand de gauche de l'opérateur « . » doit avoir un type classe, et non un type pointeur. En revanche, l'opérand de gauche de « ->* » doit obligatoirement être un pointeur.) La forme correcte serait donc soit : (objet->*(objet->function[id]))( param ) ; si objet a un type pointeur, soit : (objet.*(objet.function[id]))( param ) ; si objet a un type de classe.
Dans les deux cas, le sous-expression « (objet.function[id]) » ou « (objet->function[id]) » lit un pointeur à fonction membre du tableau dans l'objet désigné par « objet », et appelle la fonction membre qu'il désigne sur l'objet désigné par « objet ». L'objet désigné par « objet » sert bien deux fois, et chaque fois, on pourrait très bien utiliser un autre objet, de façon indépendante.
-- 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
Bruno CAUSSE wrote:
dans l'article 1150274706.189638.78370@p79g2000cwp.googlegroups.com, kanz e à
kanze@gabi-soft.fr a écrit le 14/06/06 10:45 :
[...]
Merci maintenant ca fonctionne :-)
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Le C++ est un langage assez complexe, qui exige un certain
apprentissage. Et une attention assez poussée aux détails : des
distinctions du genre déclaration / définition ou initialisation
/ affectation sont parfois d'une grande importance, même si la
distinction n'est pas toujours claire pour un débuttant.
J'ai meme eu du mal a comprendre pourquoi entre ta solution et
celle de fabien il manquait les * et & , oui :-) a cause du
typedef.
Non seulement. Lors de l'utilisation, il y a des conversions
implicites, etc., qui fait que certains opérateurs sont parfois
facultatifs. Moi, je les mets quand même, en général, parce que
je trouve que ça rend plus clair ce qu'on fait, mais d'autres
les laissent systèmatiquement. Donc :
extern int f() ;
int (*pf)() ; // C'est un pointeur à une fonction...
pf = &f ; // On l'initialise avec l'adresse de f.
pf = f ; // Aussi. Il y a conversion implicite.
(*pf)() ; // On appelle la fonction...
pf() ; // Aussi... on peut se servir d'un
// pointeur à une fonction exactement
// comme le nom d'une fonction.
En gros, pour des raisons historiques, on peut utiliser le nom
d'une fonction et son adresse de façon interchangeable ; le
compilateur comprend d'après le contexte ce qu'il faut, et fait
les conversions nécessaire. Personellement, je choisis d'être
explicit quand même, mais il y a une grande tradition qui fait
le contraire, et il y a même certains idiomes (avec les
templates) qui y compte.
Mais plein de choses m'echappent, par ex:
Utilisation a l'interieur d'une methode membre
((this)->*(function[id]))(param)
Attention : il s'agit ici de l'utilisaton d'un pointeur à
fonction membre (non-statique). La syntaxe autour des pointeurs
à membre est assez complex ; à ta place, j'attendrais avoir
maîtriser des bases avant de s'y venturer, d'autant plus que ce
n'est pas souvent utile, et jamais nécessaire. J'aborderais même
les templates avant -- non qu'ils soient moins complexe, mais
ils sont de beaucoup plus utiles.
Et dans une methode d'une autre classe
((objet)->*(objet.function[id]))(param) pourquoi le 2e "objet"?
Parce que fonction est un membre (non-statique). Sans
l'« objet », c'est implicitement comme si on avait écrit
« this->function » ; c-à-d qu'on accederait au tableau membre
de cet objet, et non à celui de l'objet « objet ». (En
revanche, l'expression telle que tu l'as réproduit ci-dessus ne
peut pas être légal. Si « objet » est un pointeur,
« objet.function » ne passe pas, parce que l'opérand de gauche
de l'opérateur « . » doit avoir un type classe, et non un type
pointeur. En revanche, l'opérand de gauche de « ->* » doit
obligatoirement être un pointeur.) La forme correcte serait donc
soit :
(objet->*(objet->function[id]))( param ) ;
si objet a un type pointeur, soit :
(objet.*(objet.function[id]))( param ) ;
si objet a un type de classe.
Dans les deux cas, le sous-expression « (objet.function[id]) »
ou « (objet->function[id]) » lit un pointeur à fonction membre
du tableau dans l'objet désigné par « objet », et appelle la
fonction membre qu'il désigne sur l'objet désigné par
« objet ». L'objet désigné par « objet » sert bien deux
fois, et chaque fois, on pourrait très bien utiliser un autre
objet, de façon indépendante.
--
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
dans l'article , kanz e à a écrit le 14/06/06 10:45 :
[...]
Merci maintenant ca fonctionne :-)
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Le C++ est un langage assez complexe, qui exige un certain apprentissage. Et une attention assez poussée aux détails : des distinctions du genre déclaration / définition ou initialisation / affectation sont parfois d'une grande importance, même si la distinction n'est pas toujours claire pour un débuttant.
J'ai meme eu du mal a comprendre pourquoi entre ta solution et celle de fabien il manquait les * et & , oui :-) a cause du typedef.
Non seulement. Lors de l'utilisation, il y a des conversions implicites, etc., qui fait que certains opérateurs sont parfois facultatifs. Moi, je les mets quand même, en général, parce que je trouve que ça rend plus clair ce qu'on fait, mais d'autres les laissent systèmatiquement. Donc :
extern int f() ; int (*pf)() ; // C'est un pointeur à une fonction... pf = &f ; // On l'initialise avec l'adresse de f. pf = f ; // Aussi. Il y a conversion implicite.
(*pf)() ; // On appelle la fonction... pf() ; // Aussi... on peut se servir d'un // pointeur à une fonction exactement // comme le nom d'une fonction.
En gros, pour des raisons historiques, on peut utiliser le nom d'une fonction et son adresse de façon interchangeable ; le compilateur comprend d'après le contexte ce qu'il faut, et fait les conversions nécessaire. Personellement, je choisis d'être explicit quand même, mais il y a une grande tradition qui fait le contraire, et il y a même certains idiomes (avec les templates) qui y compte.
Mais plein de choses m'echappent, par ex:
Utilisation a l'interieur d'une methode membre
((this)->*(function[id]))(param)
Attention : il s'agit ici de l'utilisaton d'un pointeur à fonction membre (non-statique). La syntaxe autour des pointeurs à membre est assez complex ; à ta place, j'attendrais avoir maîtriser des bases avant de s'y venturer, d'autant plus que ce n'est pas souvent utile, et jamais nécessaire. J'aborderais même les templates avant -- non qu'ils soient moins complexe, mais ils sont de beaucoup plus utiles.
Et dans une methode d'une autre classe
((objet)->*(objet.function[id]))(param) pourquoi le 2e "objet"?
Parce que fonction est un membre (non-statique). Sans l'« objet », c'est implicitement comme si on avait écrit « this->function » ; c-à-d qu'on accederait au tableau membre de cet objet, et non à celui de l'objet « objet ». (En revanche, l'expression telle que tu l'as réproduit ci-dessus ne peut pas être légal. Si « objet » est un pointeur, « objet.function » ne passe pas, parce que l'opérand de gauche de l'opérateur « . » doit avoir un type classe, et non un type pointeur. En revanche, l'opérand de gauche de « ->* » doit obligatoirement être un pointeur.) La forme correcte serait donc soit : (objet->*(objet->function[id]))( param ) ; si objet a un type pointeur, soit : (objet.*(objet.function[id]))( param ) ; si objet a un type de classe.
Dans les deux cas, le sous-expression « (objet.function[id]) » ou « (objet->function[id]) » lit un pointeur à fonction membre du tableau dans l'objet désigné par « objet », et appelle la fonction membre qu'il désigne sur l'objet désigné par « objet ». L'objet désigné par « objet » sert bien deux fois, et chaque fois, on pourrait très bien utiliser un autre objet, de façon indépendante.
-- 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
Fabien LE LEZ
On Wed, 14 Jun 2006 15:33:28 +0200, Bruno CAUSSE :
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça fait partie des "coins poussiéreux" du langage, dont je ne me sers quasiment jamais.
On Wed, 14 Jun 2006 15:33:28 +0200, Bruno CAUSSE <envoi@lesSpam.fr>:
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je
ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça
fait partie des "coins poussiéreux" du langage, dont je ne me sers
quasiment jamais.
On Wed, 14 Jun 2006 15:33:28 +0200, Bruno CAUSSE :
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça fait partie des "coins poussiéreux" du langage, dont je ne me sers quasiment jamais.
Jean-Claude Arbaut
Fabien LE LEZ wrote:
On Wed, 14 Jun 2006 15:33:28 +0200, Bruno CAUSSE :
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça fait partie des "coins poussiéreux" du langage, dont je ne me sers quasiment jamais.
C'est très différent des pointeurs de fonction du C ?
Fabien LE LEZ wrote:
On Wed, 14 Jun 2006 15:33:28 +0200, Bruno CAUSSE <envoi@lesSpam.fr>:
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je
ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça
fait partie des "coins poussiéreux" du langage, dont je ne me sers
quasiment jamais.
C'est très différent des pointeurs de fonction du C ?
On Wed, 14 Jun 2006 15:33:28 +0200, Bruno CAUSSE :
Mais c'est loin d'etre evident pour le simple boetien que je suis.
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça fait partie des "coins poussiéreux" du langage, dont je ne me sers quasiment jamais.
C'est très différent des pointeurs de fonction du C ?
Olivier Miakinen
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça fait partie des "coins poussiéreux" du langage, dont je ne me sers quasiment jamais.
C'est très différent des pointeurs de fonction du C ?
Si j'ai bien compris leurs réponses, Matthieu et kanze avaient l'air de penser que non.
Mais je pense que, dans de nombreux cas où l'utilisation de pointeurs de fonctions peut s'avérer utile en C, on pourrait s'en sortir avec des sous-classes et des fonctions virtuelles en C++. C'est en ce sens que je comprends la remarque de Fabien : ça existe, il y a probablement des cas où ce sera utile même en C++, mais il n'a quasiment jamais rencontré de tels cas.
-- Olivier Miakinen Troll du plus sage chez les conviviaux : le nouveau venu, avec son clan, s'infiltre dans les groupes de nouvelles. (3 c.)
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je
ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça
fait partie des "coins poussiéreux" du langage, dont je ne me sers
quasiment jamais.
C'est très différent des pointeurs de fonction du C ?
Si j'ai bien compris leurs réponses, Matthieu et kanze avaient l'air de
penser que non.
Mais je pense que, dans de nombreux cas où l'utilisation de pointeurs
de fonctions peut s'avérer utile en C, on pourrait s'en sortir avec des
sous-classes et des fonctions virtuelles en C++. C'est en ce sens que je
comprends la remarque de Fabien : ça existe, il y a probablement des cas
où ce sera utile même en C++, mais il n'a quasiment jamais rencontré de
tels cas.
--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)
Je te comprends. Bien qu'ayant quelques années d'expérience en C++, je ne comprends toujours pas grand-chose aux pointeurs de fonctions. Ça fait partie des "coins poussiéreux" du langage, dont je ne me sers quasiment jamais.
C'est très différent des pointeurs de fonction du C ?
Si j'ai bien compris leurs réponses, Matthieu et kanze avaient l'air de penser que non.
Mais je pense que, dans de nombreux cas où l'utilisation de pointeurs de fonctions peut s'avérer utile en C, on pourrait s'en sortir avec des sous-classes et des fonctions virtuelles en C++. C'est en ce sens que je comprends la remarque de Fabien : ça existe, il y a probablement des cas où ce sera utile même en C++, mais il n'a quasiment jamais rencontré de tels cas.
-- Olivier Miakinen Troll du plus sage chez les conviviaux : le nouveau venu, avec son clan, s'infiltre dans les groupes de nouvelles. (3 c.)