Puis-je appeler la fonction virtuelle d’une classe de base si je la remplace?

Disons que j’ai des classes Foo et Bar définies comme ceci:

 class Foo { public: int x; virtual void printStuff() { std::cout << x << std::endl; } }; class Bar : public Foo { public: int y; void printStuff() { // I would like to call Foo.printStuff() here... std::cout << y << std::endl; } }; 

Comme annoté dans le code, j’aimerais pouvoir appeler la fonction de la classe de base que je remplace. En Java, il y a la syntaxe super.funcname() . Est-ce possible en C ++?

La syntaxe C ++ est comme ceci:

 class Bar : public Foo { // ... void printStuff() { Foo::printStuff(); // calls base class' function } }; 

Oui,

 class Bar : public Foo { ... void printStuff() { Foo::printStuff(); } }; 

C’est la même chose que super en Java, sauf qu’il permet d’appeler des implémentations à partir de différentes bases lorsque vous avez plusieurs inheritances.

 class Foo { public: virtual void foo() { ... } }; class Baz { public: virtual void foo() { ... } }; class Bar : public Foo, public Baz { public: virtual void foo() { // Choose one, or even call both if you need to. Foo::foo(); Baz::foo(); } }; 

Parfois, vous devez appeler l’implémentation de la classe de base lorsque vous n’êtes pas dans la fonction dérivée … Cela fonctionne toujours:

 struct Base { virtual int Foo() { return -1; } }; struct Derived : public Base { virtual int Foo() { return -2; } }; int main(int argc, char* argv[]) { Base *x = new Derived; ASSERT(-2 == x->Foo()); //syntax is sortingppy but it works ASSERT(-1 == x->Base::Foo()); return 0; } 

Juste au cas où vous feriez cela pour beaucoup de fonctions dans votre classe:

 class Foo { public: virtual void f1() { // ... } virtual void f2() { // ... } //... }; class Bar : public Foo { private: typedef Foo super; public: void f1() { super::f1(); } }; 

Cela pourrait permettre d’économiser un peu d’écriture si vous souhaitez renommer Foo.

Si vous voulez appeler une fonction de classe de base à partir de sa classe dérivée, vous pouvez simplement appeler à l’intérieur de la fonction surchargée en mentionnant le nom de la classe de base (comme Foo :: printStuff () ).

le code va ici

 #include  using namespace std; class Foo { public: int x; virtual void printStuff() { cout<<"Base Foo printStuff called"<printStuff(); } 

Encore une fois, vous pouvez déterminer à l’exécution quelle fonction appeler en utilisant l’object de cette classe (dérivé ou de base). Mais cela nécessite que votre fonction à la classe de base soit marquée comme virtuelle.

code ci-dessous

 #include  using namespace std; class Foo { public: int x; virtual void printStuff() { cout<<"Base Foo printStuff called"<printStuff();/////this call the base function foo=new Bar; foo->printStuff(); } 

vérifie ça…

 #include  class Base { public: virtual void gogo(int a) { printf(" Base :: gogo (int) \n"); }; virtual void gogo1(int a) { printf(" Base :: gogo1 (int) \n"); }; void gogo2(int a) { printf(" Base :: gogo2 (int) \n"); }; void gogo3(int a) { printf(" Base :: gogo3 (int) \n"); }; }; class Derived : protected Base { public: virtual void gogo(int a) { printf(" Derived :: gogo (int) \n"); }; void gogo1(int a) { printf(" Derived :: gogo1 (int) \n"); }; virtual void gogo2(int a) { printf(" Derived :: gogo2 (int) \n"); }; void gogo3(int a) { printf(" Derived :: gogo3 (int) \n"); }; }; int main() { std::cout << "Derived" << std::endl; auto obj = new Derived ; obj->gogo(7); obj->gogo1(7); obj->gogo2(7); obj->gogo3(7); std::cout << "Base" << std::endl; auto base = (Base*)obj; base->gogo(7); base->gogo1(7); base->gogo2(7); base->gogo3(7); std::ssortingng s; std::cout << "press any key to exit" << std::endl; std::cin >> s; return 0; } 

sortie

 Derived Derived :: gogo (int) Derived :: gogo1 (int) Derived :: gogo2 (int) Derived :: gogo3 (int) Base Derived :: gogo (int) Derived :: gogo1 (int) Base :: gogo2 (int) Base :: gogo3 (int) press any key to exit 

la meilleure façon d’utiliser la fonction base :: comme dit @sth

Oui, vous pouvez l’appeler. La syntaxe C ++ pour appeler la fonction de classe parent dans la classe enfant est

 class child: public parent { // ... void methodName() { parent::methodName(); // calls Parent class' function } }; 

En savoir plus sur la neutralisation des fonctions.