Salutations,
je suis en train de réviser mes bases en C++ et... je ne comprends pas
pourquoi le "standard committee" a mis en place le mécanisme de "function
hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement dans la classe
fille pour avoir de nouveau accès à Base::foo(int) ?
Salutations,
je suis en train de réviser mes bases en C++ et... je ne comprends pas
pourquoi le "standard committee" a mis en place le mécanisme de "function
hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement dans la classe
fille pour avoir de nouveau accès à Base::foo(int) ?
Salutations,
je suis en train de réviser mes bases en C++ et... je ne comprends pas
pourquoi le "standard committee" a mis en place le mécanisme de "function
hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement dans la classe
fille pour avoir de nouveau accès à Base::foo(int) ?
je suis en train de réviser mes bases en C++ et... je ne comprends pas
pourquoi le "standard committee" a mis en place le mécanisme de "function
hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement dans la classe
fille pour avoir de nouveau accès à Base::foo(int) ?
* Parce que les classes sont des "scopes" et que la classe
dérivée apparaît pour la recherche de nom exactement comme
un scope imbriqué dans la classe de base.
* Parce que la recherche de nom est définie de telle sorte
que quand on a trouvé un nom dans un scope, on ne cherche
pas dans les scopes englobant (ce qui n'a d'effet que pour
la surchage me semble-t'il).
je suis en train de réviser mes bases en C++ et... je ne comprends pas
pourquoi le "standard committee" a mis en place le mécanisme de "function
hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement dans la classe
fille pour avoir de nouveau accès à Base::foo(int) ?
* Parce que les classes sont des "scopes" et que la classe
dérivée apparaît pour la recherche de nom exactement comme
un scope imbriqué dans la classe de base.
* Parce que la recherche de nom est définie de telle sorte
que quand on a trouvé un nom dans un scope, on ne cherche
pas dans les scopes englobant (ce qui n'a d'effet que pour
la surchage me semble-t'il).
je suis en train de réviser mes bases en C++ et... je ne comprends pas
pourquoi le "standard committee" a mis en place le mécanisme de "function
hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement dans la classe
fille pour avoir de nouveau accès à Base::foo(int) ?
* Parce que les classes sont des "scopes" et que la classe
dérivée apparaît pour la recherche de nom exactement comme
un scope imbriqué dans la classe de base.
* Parce que la recherche de nom est définie de telle sorte
que quand on a trouvé un nom dans un scope, on ne cherche
pas dans les scopes englobant (ce qui n'a d'effet que pour
la surchage me semble-t'il).
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement
dans la classe fille pour avoir de nouveau accès à
Base::foo(int) ?
Ce n'est pas la première fois que je me pose la question, mais
je n'ai jamais trouvé de réponse satisfaisante, même après
avoir posté sur différents forums et newsgroup.
En tout cas, ce mécanisme me semble anti-intuitif...
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement
dans la classe fille pour avoir de nouveau accès à
Base::foo(int) ?
Ce n'est pas la première fois que je me pose la question, mais
je n'ai jamais trouvé de réponse satisfaisante, même après
avoir posté sur différents forums et newsgroup.
En tout cas, ce mécanisme me semble anti-intuitif...
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
Pourquoi faut il déclarer "using Base::foo ;" explicitement
dans la classe fille pour avoir de nouveau accès à
Base::foo(int) ?
Ce n'est pas la première fois que je me pose la question, mais
je n'ai jamais trouvé de réponse satisfaisante, même après
avoir posté sur différents forums et newsgroup.
En tout cas, ce mécanisme me semble anti-intuitif...
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
La loi de la moindre surprise, sans doute.
Si les deux fonctions étaient publique, c'est discutable. Mais
personellement, je n'aimerais pas que la résolution du surcharge
et la récherche du nom dépend de l'accessibilité de la fonction.
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
La loi de la moindre surprise, sans doute.
Si les deux fonctions étaient publique, c'est discutable. Mais
personellement, je n'aimerais pas que la résolution du surcharge
et la récherche du nom dépend de l'accessibilité de la fonction.
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
La loi de la moindre surprise, sans doute.
Si les deux fonctions étaient publique, c'est discutable. Mais
personellement, je n'aimerais pas que la résolution du surcharge
et la récherche du nom dépend de l'accessibilité de la fonction.
je considère également ce type de masquage comme "abusif" car les fonctions
ont des signatures différentes - qu'un compilo C K&R ne voit qu'une
fonction serait acceptable normal
[...]
la question serait alors: pourquoi le "function hiding" est basé sur les
noms et non sur les signatures de fonctions ?
si j'ai bonne mémoire -- il y a un passage là-dessus dans
D&E, mais je n'ai pas le bouquin ici -- une première version
des règles de résolution de surchage aurait posé des
problèmes -- je ne sais plus lesquels -- qu'on a évité
ainsi. Ensuite les règles de résolution de surchage ont été
modifiée, mais on n'est pas revenu sur ce choix. Quand on
s'en est rendu compte, il y avait trop d'existant.
je considère également ce type de masquage comme "abusif" car les fonctions
ont des signatures différentes - qu'un compilo C K&R ne voit qu'une
fonction serait acceptable normal
[...]
la question serait alors: pourquoi le "function hiding" est basé sur les
noms et non sur les signatures de fonctions ?
si j'ai bonne mémoire -- il y a un passage là-dessus dans
D&E, mais je n'ai pas le bouquin ici -- une première version
des règles de résolution de surchage aurait posé des
problèmes -- je ne sais plus lesquels -- qu'on a évité
ainsi. Ensuite les règles de résolution de surchage ont été
modifiée, mais on n'est pas revenu sur ce choix. Quand on
s'en est rendu compte, il y avait trop d'existant.
je considère également ce type de masquage comme "abusif" car les fonctions
ont des signatures différentes - qu'un compilo C K&R ne voit qu'une
fonction serait acceptable normal
[...]
la question serait alors: pourquoi le "function hiding" est basé sur les
noms et non sur les signatures de fonctions ?
si j'ai bonne mémoire -- il y a un passage là-dessus dans
D&E, mais je n'ai pas le bouquin ici -- une première version
des règles de résolution de surchage aurait posé des
problèmes -- je ne sais plus lesquels -- qu'on a évité
ainsi. Ensuite les règles de résolution de surchage ont été
modifiée, mais on n'est pas revenu sur ce choix. Quand on
s'en est rendu compte, il y avait trop d'existant.
[...]
Je serais très reconnaissant à quiconque pourrait me donner une bonne
raison / un bon exemple / un pointeur WWW !
[...]
Je serais très reconnaissant à quiconque pourrait me donner une bonne
raison / un bon exemple / un pointeur WWW !
[...]
Je serais très reconnaissant à quiconque pourrait me donner une bonne
raison / un bon exemple / un pointeur WWW !
Dans ce que tu as coupé il y avait:si j'ai bonne mémoire -- il y a un passage là-dessus dans
D&E, mais je n'ai pas le bouquin ici -- une première version
des règles de résolution de surchage aurait posé des
problèmes -- je ne sais plus lesquels -- qu'on a évité
ainsi. Ensuite les règles de résolution de surchage ont été
modifiée, mais on n'est pas revenu sur ce choix. Quand on
s'en est rendu compte, il y avait trop d'existant.
qui réponds plus ou moins à tes deux questions/objections
(du moins qui donne une spéculation basée sur mes souvenirs
de lecture de D&E).
Dans ce que tu as coupé il y avait:
si j'ai bonne mémoire -- il y a un passage là-dessus dans
D&E, mais je n'ai pas le bouquin ici -- une première version
des règles de résolution de surchage aurait posé des
problèmes -- je ne sais plus lesquels -- qu'on a évité
ainsi. Ensuite les règles de résolution de surchage ont été
modifiée, mais on n'est pas revenu sur ce choix. Quand on
s'en est rendu compte, il y avait trop d'existant.
qui réponds plus ou moins à tes deux questions/objections
(du moins qui donne une spéculation basée sur mes souvenirs
de lecture de D&E).
Dans ce que tu as coupé il y avait:si j'ai bonne mémoire -- il y a un passage là-dessus dans
D&E, mais je n'ai pas le bouquin ici -- une première version
des règles de résolution de surchage aurait posé des
problèmes -- je ne sais plus lesquels -- qu'on a évité
ainsi. Ensuite les règles de résolution de surchage ont été
modifiée, mais on n'est pas revenu sur ce choix. Quand on
s'en est rendu compte, il y avait trop d'existant.
qui réponds plus ou moins à tes deux questions/objections
(du moins qui donne une spéculation basée sur mes souvenirs
de lecture de D&E).
kanze wrote on 12/05/2006 16:12:
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
La loi de la moindre surprise, sans doute.
Si les deux fonctions étaient publique, c'est discutable.
Mais personellement, je n'aimerais pas que la résolution du
surcharge et la récherche du nom dépend de l'accessibilité de
la fonction.
tu as raison sur le fait que rédigé comme tel les fonctions
membres sont privées, je pense que la question n'incluait pas
ce point, les "class" pouvant être lû comme des "struct" -
sinon parler de masquage par scope vs par surcharge vs par
modifiers va être difficile.
tu as raison aussi sur le fait que l'accessibilité ne doit pas
rendre imprévisible la surcharge, mais également sur ce point,
pourquoi la "surcharge entre parent" serait plus compliqué
(nécessite le "fonction hiding") que la "surcharge locale"
n'utilise (heureusement) pas ?
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
kanze wrote on 12/05/2006 16:12:
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
La loi de la moindre surprise, sans doute.
Si les deux fonctions étaient publique, c'est discutable.
Mais personellement, je n'aimerais pas que la résolution du
surcharge et la récherche du nom dépend de l'accessibilité de
la fonction.
tu as raison sur le fait que rédigé comme tel les fonctions
membres sont privées, je pense que la question n'incluait pas
ce point, les "class" pouvant être lû comme des "struct" -
sinon parler de masquage par scope vs par surcharge vs par
modifiers va être difficile.
tu as raison aussi sur le fait que l'accessibilité ne doit pas
rendre imprévisible la surcharge, mais également sur ce point,
pourquoi la "surcharge entre parent" serait plus compliqué
(nécessite le "fonction hiding") que la "surcharge locale"
n'utilise (heureusement) pas ?
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
kanze wrote on 12/05/2006 16:12:
je suis en train de réviser mes bases en C++ et... je ne
comprends pas pourquoi le "standard committee" a mis en place
le mécanisme de "function hiding" dans le langage.
class Base {
void foo( int ) {}
};
class Derived: public Base {
void foo( char const [] ) {}
};
alors la méthode Base::foo(int) est cachée dans la classe
fille Derived ?
La loi de la moindre surprise, sans doute.
Si les deux fonctions étaient publique, c'est discutable.
Mais personellement, je n'aimerais pas que la résolution du
surcharge et la récherche du nom dépend de l'accessibilité de
la fonction.
tu as raison sur le fait que rédigé comme tel les fonctions
membres sont privées, je pense que la question n'incluait pas
ce point, les "class" pouvant être lû comme des "struct" -
sinon parler de masquage par scope vs par surcharge vs par
modifiers va être difficile.
tu as raison aussi sur le fait que l'accessibilité ne doit pas
rendre imprévisible la surcharge, mais également sur ce point,
pourquoi la "surcharge entre parent" serait plus compliqué
(nécessite le "fonction hiding") que la "surcharge locale"
n'utilise (heureusement) pas ?
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
Mon point reste. Pour les fonctions privées, toute autre
solution serait problamatique. Du coup, l'argument, c'est
l'orthogonalité -- et c'est un argument du poids, à mon avis,
parce qu'elle rend le langage plus facile à comprendre et à
enseigner.
Note que Java a d'autres règles, mais qu'en Java, il y a une
manque d'orthogonalité énorme -- private joue sur la visibilité
(et non l'accessabilité), à l'encontre de public ou protected ;
les règles qui concerne les variables sont différentes que
celles des fonctions, etc., etc.
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
Je ne comprends pas trop ton point ici.
Dans Base, les fonctions membres de Base sont visibles.
Dans Derived, les fonctions membres de Derived.
Ça me semble extrèmement logique et orthogonal.
Imagine plutôt quelque chose du genre :
class Base {
void toto( int ) ;
public:
void toto( char* ) ;
} ;
class Derived : public Base {
public:
void toto( double ) ;
} ;
Est-ce que ça te semblerais cohérent que dans Derived, une des
toto de Base soit visible, et l'autre non ?
(C'est effectivement le cas en Java, par exemple.
Mon point reste. Pour les fonctions privées, toute autre
solution serait problamatique. Du coup, l'argument, c'est
l'orthogonalité -- et c'est un argument du poids, à mon avis,
parce qu'elle rend le langage plus facile à comprendre et à
enseigner.
Note que Java a d'autres règles, mais qu'en Java, il y a une
manque d'orthogonalité énorme -- private joue sur la visibilité
(et non l'accessabilité), à l'encontre de public ou protected ;
les règles qui concerne les variables sont différentes que
celles des fonctions, etc., etc.
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
Je ne comprends pas trop ton point ici.
Dans Base, les fonctions membres de Base sont visibles.
Dans Derived, les fonctions membres de Derived.
Ça me semble extrèmement logique et orthogonal.
Imagine plutôt quelque chose du genre :
class Base {
void toto( int ) ;
public:
void toto( char* ) ;
} ;
class Derived : public Base {
public:
void toto( double ) ;
} ;
Est-ce que ça te semblerais cohérent que dans Derived, une des
toto de Base soit visible, et l'autre non ?
(C'est effectivement le cas en Java, par exemple.
Mon point reste. Pour les fonctions privées, toute autre
solution serait problamatique. Du coup, l'argument, c'est
l'orthogonalité -- et c'est un argument du poids, à mon avis,
parce qu'elle rend le langage plus facile à comprendre et à
enseigner.
Note que Java a d'autres règles, mais qu'en Java, il y a une
manque d'orthogonalité énorme -- private joue sur la visibilité
(et non l'accessabilité), à l'encontre de public ou protected ;
les règles qui concerne les variables sont différentes que
celles des fonctions, etc., etc.
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
Je ne comprends pas trop ton point ici.
Dans Base, les fonctions membres de Base sont visibles.
Dans Derived, les fonctions membres de Derived.
Ça me semble extrèmement logique et orthogonal.
Imagine plutôt quelque chose du genre :
class Base {
void toto( int ) ;
public:
void toto( char* ) ;
} ;
class Derived : public Base {
public:
void toto( double ) ;
} ;
Est-ce que ça te semblerais cohérent que dans Derived, une des
toto de Base soit visible, et l'autre non ?
(C'est effectivement le cas en Java, par exemple.
James Kanze wrote on 13/05/2006 11:47:Mon point reste. Pour les fonctions privées, toute autre
solution serait problamatique. Du coup, l'argument, c'est
l'orthogonalité -- et c'est un argument du poids, à mon
avis,
c'est à dire ? faut-il comprendre que le compilo va avoir
suffisamment de mal à remonter l'arborescense de classes lors
de la recherche d'une méthode à signature (prototype) donnée,
qu'il sera vraiment en peine de traiter, en plus, un modifier
'public' ou 'private' ??
btw, si tu peux expliciter 'orthogonalité' dans le cadre des
règles d'accès, je ne suis pas sur de partager le même sens.
Note que Java a d'autres règles, mais qu'en Java, il y a une
manque d'orthogonalité énorme -- private joue sur la
visibilité (et non l'accessabilité), à l'encontre de public
ou protected ; les règles qui concerne les variables sont
différentes que celles des fonctions, etc., etc.
comprends pas ! private, protected, package ou public sont
gérés avec les mêmes règles, et ces règles s'appliquent à
l'identique à une donnée ou une fonction membre.
ce qui change entre Java et C++, c'est ce que l'on peut
appeler 'visibilité' qui contraint plus fortement ce qui est
accessible depuis l'endroit où en se trouve (ce que l'on
voit). ainsi ton exemple (autre thread)
public base clone() {
return doClone();
}
private abstract base doClone();
ne pourrait pas fonctionner car dans le contexte de "clone"
les seules méthodes privées accessibles sont celles de base.
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
Je ne comprends pas trop ton point ici.
mon point est:
Derived d;
d.foo(1); error (plutot unexpected, le int sera casté en float)
d.foo("a"); error
Dans Base, les fonctions membres de Base sont visibles.
Dans Derived, les fonctions membres de Derived.
Ça me semble extrèmement logique et orthogonal.
le point est, depuis le début, comment invoquer (depuis
l'extérieur) les services de la classe (pas comment cette
classe implémente sa toutouille interne).Imagine plutôt quelque chose du genre :
class Base {
void toto( int ) ;
public:
void toto( char* ) ;
} ;
class Derived : public Base {
public:
void toto( double ) ;
} ;
Est-ce que ça te semblerais cohérent que dans Derived, une
des toto de Base soit visible, et l'autre non ?
me semblerait-il logique qu'une fonction publique
(toto(char*)) dont Derived hérite publiquement soit visible
(spontanément publique sans using) ? ben oui sans hésitation.
qu'il ne soit pas possible d'accéder (via une instance de
Derived) à toto(int) me paraitra également tout à fait normal
puisqu'elle est privée.
au delà de ces "paraître" ce qui est formulé ici est la seule
lecture des attributs d'accès définis par ces classes - une
lecture simple et directe qu'il aurait été facile de
comprendre et d'enseigner.
(C'est effectivement le cas en Java, par exemple.
en effet.
James Kanze wrote on 13/05/2006 11:47:
Mon point reste. Pour les fonctions privées, toute autre
solution serait problamatique. Du coup, l'argument, c'est
l'orthogonalité -- et c'est un argument du poids, à mon
avis,
c'est à dire ? faut-il comprendre que le compilo va avoir
suffisamment de mal à remonter l'arborescense de classes lors
de la recherche d'une méthode à signature (prototype) donnée,
qu'il sera vraiment en peine de traiter, en plus, un modifier
'public' ou 'private' ??
btw, si tu peux expliciter 'orthogonalité' dans le cadre des
règles d'accès, je ne suis pas sur de partager le même sens.
Note que Java a d'autres règles, mais qu'en Java, il y a une
manque d'orthogonalité énorme -- private joue sur la
visibilité (et non l'accessabilité), à l'encontre de public
ou protected ; les règles qui concerne les variables sont
différentes que celles des fonctions, etc., etc.
comprends pas ! private, protected, package ou public sont
gérés avec les mêmes règles, et ces règles s'appliquent à
l'identique à une donnée ou une fonction membre.
ce qui change entre Java et C++, c'est ce que l'on peut
appeler 'visibilité' qui contraint plus fortement ce qui est
accessible depuis l'endroit où en se trouve (ce que l'on
voit). ainsi ton exemple (autre thread)
public base clone() {
return doClone();
}
private abstract base doClone();
ne pourrait pas fonctionner car dans le contexte de "clone"
les seules méthodes privées accessibles sont celles de base.
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
Je ne comprends pas trop ton point ici.
mon point est:
Derived d;
d.foo(1); error (plutot unexpected, le int sera casté en float)
d.foo("a"); error
Dans Base, les fonctions membres de Base sont visibles.
Dans Derived, les fonctions membres de Derived.
Ça me semble extrèmement logique et orthogonal.
le point est, depuis le début, comment invoquer (depuis
l'extérieur) les services de la classe (pas comment cette
classe implémente sa toutouille interne).
Imagine plutôt quelque chose du genre :
class Base {
void toto( int ) ;
public:
void toto( char* ) ;
} ;
class Derived : public Base {
public:
void toto( double ) ;
} ;
Est-ce que ça te semblerais cohérent que dans Derived, une
des toto de Base soit visible, et l'autre non ?
me semblerait-il logique qu'une fonction publique
(toto(char*)) dont Derived hérite publiquement soit visible
(spontanément publique sans using) ? ben oui sans hésitation.
qu'il ne soit pas possible d'accéder (via une instance de
Derived) à toto(int) me paraitra également tout à fait normal
puisqu'elle est privée.
au delà de ces "paraître" ce qui est formulé ici est la seule
lecture des attributs d'accès définis par ces classes - une
lecture simple et directe qu'il aurait été facile de
comprendre et d'enseigner.
(C'est effectivement le cas en Java, par exemple.
en effet.
James Kanze wrote on 13/05/2006 11:47:Mon point reste. Pour les fonctions privées, toute autre
solution serait problamatique. Du coup, l'argument, c'est
l'orthogonalité -- et c'est un argument du poids, à mon
avis,
c'est à dire ? faut-il comprendre que le compilo va avoir
suffisamment de mal à remonter l'arborescense de classes lors
de la recherche d'une méthode à signature (prototype) donnée,
qu'il sera vraiment en peine de traiter, en plus, un modifier
'public' ou 'private' ??
btw, si tu peux expliciter 'orthogonalité' dans le cadre des
règles d'accès, je ne suis pas sur de partager le même sens.
Note que Java a d'autres règles, mais qu'en Java, il y a une
manque d'orthogonalité énorme -- private joue sur la
visibilité (et non l'accessabilité), à l'encontre de public
ou protected ; les règles qui concerne les variables sont
différentes que celles des fonctions, etc., etc.
comprends pas ! private, protected, package ou public sont
gérés avec les mêmes règles, et ces règles s'appliquent à
l'identique à une donnée ou une fonction membre.
ce qui change entre Java et C++, c'est ce que l'on peut
appeler 'visibilité' qui contraint plus fortement ce qui est
accessible depuis l'endroit où en se trouve (ce que l'on
voit). ainsi ton exemple (autre thread)
public base clone() {
return doClone();
}
private abstract base doClone();
ne pourrait pas fonctionner car dans le contexte de "clone"
les seules méthodes privées accessibles sont celles de base.
struct Base {
void foo( int ) {}
void foo( char* ) {}
};
les 2 sont visibles.
struct Derived: Base {
void foo( float ) {}
};
les 2 Base::foo() sont masquées.
Je ne comprends pas trop ton point ici.
mon point est:
Derived d;
d.foo(1); error (plutot unexpected, le int sera casté en float)
d.foo("a"); error
Dans Base, les fonctions membres de Base sont visibles.
Dans Derived, les fonctions membres de Derived.
Ça me semble extrèmement logique et orthogonal.
le point est, depuis le début, comment invoquer (depuis
l'extérieur) les services de la classe (pas comment cette
classe implémente sa toutouille interne).Imagine plutôt quelque chose du genre :
class Base {
void toto( int ) ;
public:
void toto( char* ) ;
} ;
class Derived : public Base {
public:
void toto( double ) ;
} ;
Est-ce que ça te semblerais cohérent que dans Derived, une
des toto de Base soit visible, et l'autre non ?
me semblerait-il logique qu'une fonction publique
(toto(char*)) dont Derived hérite publiquement soit visible
(spontanément publique sans using) ? ben oui sans hésitation.
qu'il ne soit pas possible d'accéder (via une instance de
Derived) à toto(int) me paraitra également tout à fait normal
puisqu'elle est privée.
au delà de ces "paraître" ce qui est formulé ici est la seule
lecture des attributs d'accès définis par ces classes - une
lecture simple et directe qu'il aurait été facile de
comprendre et d'enseigner.
(C'est effectivement le cas en Java, par exemple.
en effet.