Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Loïc Joly
PurL wrote:
Bonjour,
Pouvez-vous me dire quel comportement y'a t-il entre ces 2 déclarations :
1/
class A { ... virtual void fct() = 0; ... };
class B : public A { ... virtual void fct() = 0; ... };
class C : public B { ... void fct() { //code} ... };
Dans ce cas, la fonction B::fct peut être définie (le =0 n'empêche pas ça). Exemple où ça peut servir : fct est une fonction "en cascade", genre save, c'est à dire que la fonction de la classe dérivée doit commencer par appeler la version de la classe de base. Quand on écrit B, classe abstraite pour d'autres raisons, on a quand même besoin d'écrire la fonction B::save pour sauver les données correspondant à B. Et on n'a pas envie que les gens qui dérivent de B oublient de définir une fonction save à eux. Donc on déclare B::save virtuelle pure, et on la défini quand même (remarque : Souvent, dans ce genre de cas, la fonction est protected).
-- Loïc
PurL wrote:
Bonjour,
Pouvez-vous me dire quel comportement y'a t-il entre ces 2 déclarations :
1/
class A
{
...
virtual void fct() = 0;
...
};
class B : public A
{
...
virtual void fct() = 0;
...
};
class C : public B
{
...
void fct() { //code}
...
};
Dans ce cas, la fonction B::fct peut être définie (le =0 n'empêche pas
ça). Exemple où ça peut servir : fct est une fonction "en cascade",
genre save, c'est à dire que la fonction de la classe dérivée doit
commencer par appeler la version de la classe de base. Quand on écrit B,
classe abstraite pour d'autres raisons, on a quand même besoin d'écrire
la fonction B::save pour sauver les données correspondant à B. Et on n'a
pas envie que les gens qui dérivent de B oublient de définir une
fonction save à eux. Donc on déclare B::save virtuelle pure, et on la
défini quand même (remarque : Souvent, dans ce genre de cas, la fonction
est protected).
Pouvez-vous me dire quel comportement y'a t-il entre ces 2 déclarations :
1/
class A { ... virtual void fct() = 0; ... };
class B : public A { ... virtual void fct() = 0; ... };
class C : public B { ... void fct() { //code} ... };
Dans ce cas, la fonction B::fct peut être définie (le =0 n'empêche pas ça). Exemple où ça peut servir : fct est une fonction "en cascade", genre save, c'est à dire que la fonction de la classe dérivée doit commencer par appeler la version de la classe de base. Quand on écrit B, classe abstraite pour d'autres raisons, on a quand même besoin d'écrire la fonction B::save pour sauver les données correspondant à B. Et on n'a pas envie que les gens qui dérivent de B oublient de définir une fonction save à eux. Donc on déclare B::save virtuelle pure, et on la défini quand même (remarque : Souvent, dans ce genre de cas, la fonction est protected).
-- Loïc
Jean-Marc Bourguet
"PurL" writes:
Bonjour,
Pouvez-vous me dire quel comportement y'a t-il entre ces 2 déclarations :
1/
class A { ... virtual void fct() = 0; ... };
class B : public A { ... virtual void fct() = 0; ... }; 2/
class B : public A { ... ... };
La différence est que fct n'est pas redéfinie au sein de B.
Outre la possibilite de definir fct (voir message de Loïc), il me semble que ca peut changer la recherche des noms; si fct est surcharge dans B, un appel a travers un B ne trouvera pas void fct() venant de A sans la declaration.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
"PurL" <purl-nospam@chez.com> writes:
Bonjour,
Pouvez-vous me dire quel comportement y'a t-il entre ces 2 déclarations :
1/
class A
{
...
virtual void fct() = 0;
...
};
class B : public A
{
...
virtual void fct() = 0;
...
};
2/
class B : public A
{
...
...
};
La différence est que fct n'est pas redéfinie au sein de B.
Outre la possibilite de definir fct (voir message de Loïc), il me
semble que ca peut changer la recherche des noms; si fct est surcharge
dans B, un appel a travers un B ne trouvera pas void fct() venant de A
sans la declaration.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Pouvez-vous me dire quel comportement y'a t-il entre ces 2 déclarations :
1/
class A { ... virtual void fct() = 0; ... };
class B : public A { ... virtual void fct() = 0; ... }; 2/
class B : public A { ... ... };
La différence est que fct n'est pas redéfinie au sein de B.
Outre la possibilite de definir fct (voir message de Loïc), il me semble que ca peut changer la recherche des noms; si fct est surcharge dans B, un appel a travers un B ne trouvera pas void fct() venant de A sans la declaration.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
PurL
Dans ce cas, la fonction B::fct peut être définie (le =0 n'empêche pas ça). Exemple où ça peut servir : fct est une fonction "en cascade", genre save, c'est à dire que la fonction de la classe dérivée doit commencer par appeler la version de la classe de base. Quand on écrit B, classe abstraite pour d'autres raisons, on a quand même besoin d'écrire la fonction B::save pour sauver les données correspondant à B. Et on n'a pas envie que les gens qui dérivent de B oublient de définir une fonction save à eux. Donc on déclare B::save virtuelle pure, et on la défini quand même (remarque : Souvent, dans ce genre de cas, la fonction est protected).
Je suis d'accord, c'est meme l'effet désirée (cascade) sauf que je n'ai pas besoin ne redéfinir la fct de B. Je voulais juste savoir ce que cela changeait pour A. Si j'ai bien compris, qu'il y ait la déclaration virtual void fct() = 0; dans B ou pas, ne change rien pour A ? J'avais un doute dans le fait de ne pas déclarer fct dans B de "casser" la chaine de l'héritage...
pouvez-vous confirmer ?
Merci,
PurL
Dans ce cas, la fonction B::fct peut être définie (le =0 n'empêche pas
ça). Exemple où ça peut servir : fct est une fonction "en cascade",
genre save, c'est à dire que la fonction de la classe dérivée doit
commencer par appeler la version de la classe de base. Quand on écrit
B, classe abstraite pour d'autres raisons, on a quand même besoin
d'écrire la fonction B::save pour sauver les données correspondant à
B. Et on n'a pas envie que les gens qui dérivent de B oublient de
définir une fonction save à eux. Donc on déclare B::save virtuelle
pure, et on la défini quand même (remarque : Souvent, dans ce genre
de cas, la fonction est protected).
Je suis d'accord, c'est meme l'effet désirée (cascade) sauf que je n'ai pas
besoin ne redéfinir la fct de B. Je voulais juste savoir ce que cela
changeait pour A.
Si j'ai bien compris, qu'il y ait la déclaration virtual void fct() = 0;
dans B ou pas, ne change rien pour A ?
J'avais un doute dans le fait de ne pas déclarer fct dans B de "casser" la
chaine de l'héritage...
Dans ce cas, la fonction B::fct peut être définie (le =0 n'empêche pas ça). Exemple où ça peut servir : fct est une fonction "en cascade", genre save, c'est à dire que la fonction de la classe dérivée doit commencer par appeler la version de la classe de base. Quand on écrit B, classe abstraite pour d'autres raisons, on a quand même besoin d'écrire la fonction B::save pour sauver les données correspondant à B. Et on n'a pas envie que les gens qui dérivent de B oublient de définir une fonction save à eux. Donc on déclare B::save virtuelle pure, et on la défini quand même (remarque : Souvent, dans ce genre de cas, la fonction est protected).
Je suis d'accord, c'est meme l'effet désirée (cascade) sauf que je n'ai pas besoin ne redéfinir la fct de B. Je voulais juste savoir ce que cela changeait pour A. Si j'ai bien compris, qu'il y ait la déclaration virtual void fct() = 0; dans B ou pas, ne change rien pour A ? J'avais un doute dans le fait de ne pas déclarer fct dans B de "casser" la chaine de l'héritage...
pouvez-vous confirmer ?
Merci,
PurL
Alexandre
Si j'ai bien compris, qu'il y ait la déclaration virtual void fct() = 0; dans B ou pas, ne change rien pour A ?
oui.
J'avais un doute dans le fait de ne pas déclarer fct dans B de "casser" la chaine de l'héritage...
non, n'étant pas redéclarée, la version de A est utilisée, donc la fonction est présente mais en virtuelle pure.
pouvez-vous confirmer ?
Merci,
PurL
Si j'ai bien compris, qu'il y ait la déclaration virtual void fct() = 0;
dans B ou pas, ne change rien pour A ?
oui.
J'avais un doute dans le fait de ne pas déclarer fct dans B de "casser" la
chaine de l'héritage...
non, n'étant pas redéclarée, la version de A est utilisée, donc la fonction
est présente mais en virtuelle pure.
Si j'ai bien compris, qu'il y ait la déclaration virtual void fct() = 0; dans B ou pas, ne change rien pour A ?
oui.
J'avais un doute dans le fait de ne pas déclarer fct dans B de "casser" la chaine de l'héritage...
non, n'étant pas redéclarée, la version de A est utilisée, donc la fonction est présente mais en virtuelle pure.
pouvez-vous confirmer ?
Merci,
PurL
drkm
Jean-Marc Bourguet writes:
"PurL" writes:
1/
class A { virtual void fct() = 0; };
class B : public A { virtual void fct() = 0; };
2/
class B : public A { };
La différence est que fct n'est pas redéfinie au sein de B.
Outre la possibilite de definir fct (voir message de Loïc), il me semble que ca peut changer la recherche des noms; si fct est surcharge dans B, un appel a travers un B ne trouvera pas void fct() venant de A sans la declaration.
J'ai du mal à comprendre ce que tu veux dire. En tout cas, ceci fonctionne comme prévu :
struct A { virtual void fct() = 0 ; } ; struct B : A { virtual void fct() = 0 ; } ; struct C : B { void fct() { std::cout << "C::fct()" << std::endl ; } } ;
struct X { virtual void fct() = 0 ; } ; struct Y : X { } ; struct Z : Y { void fct() { std::cout << "Z::fct()" << std::endl ; } } ;
int main() { B * b = new C() ; Y * y = new Z() ; b->fct() ; y->fct() ; } ~> g++ -o fclcxx fclcxx.cc -Wall -ansi -pedantic ~> ./fclcxx C::fct() Z::fct()
--drkm
Jean-Marc Bourguet <jm@bourguet.org> writes:
"PurL" <purl-nospam@chez.com> writes:
1/
class A
{
virtual void fct() = 0;
};
class B : public A
{
virtual void fct() = 0;
};
2/
class B : public A
{
};
La différence est que fct n'est pas redéfinie au sein de B.
Outre la possibilite de definir fct (voir message de Loïc), il me
semble que ca peut changer la recherche des noms; si fct est surcharge
dans B, un appel a travers un B ne trouvera pas void fct() venant de A
sans la declaration.
J'ai du mal à comprendre ce que tu veux dire. En tout cas, ceci
fonctionne comme prévu :
struct A {
virtual void fct() = 0 ;
} ;
struct B : A {
virtual void fct() = 0 ;
} ;
struct C : B {
void fct() {
std::cout << "C::fct()" << std::endl ;
}
} ;
struct X {
virtual void fct() = 0 ;
} ;
struct Y : X {
} ;
struct Z : Y {
void fct() {
std::cout << "Z::fct()" << std::endl ;
}
} ;
int main() {
B * b = new C() ;
Y * y = new Z() ;
b->fct() ;
y->fct() ;
}
~> g++ -o fclcxx fclcxx.cc -Wall -ansi -pedantic
~> ./fclcxx
C::fct()
Z::fct()
La différence est que fct n'est pas redéfinie au sein de B.
Outre la possibilite de definir fct (voir message de Loïc), il me semble que ca peut changer la recherche des noms; si fct est surcharge dans B, un appel a travers un B ne trouvera pas void fct() venant de A sans la declaration.
J'ai du mal à comprendre ce que tu veux dire. En tout cas, ceci fonctionne comme prévu :
struct A { virtual void fct() = 0 ; } ; struct B : A { virtual void fct() = 0 ; } ; struct C : B { void fct() { std::cout << "C::fct()" << std::endl ; } } ;
struct X { virtual void fct() = 0 ; } ; struct Y : X { } ; struct Z : Y { void fct() { std::cout << "Z::fct()" << std::endl ; } } ;
int main() { B * b = new C() ; Y * y = new Z() ; b->fct() ; y->fct() ; } ~> g++ -o fclcxx fclcxx.cc -Wall -ansi -pedantic ~> ./fclcxx C::fct() Z::fct()