могу ли я вызвать виртуальную функцию базового класса, если переопределяю ее?

<p>скажем, у меня есть классы <code>foo</code> и <code>bar</code>, настроенные так:</p><pre><code>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; } }; </code></pre><p>как отмечено в коде, я хотел бы иметь возможность вызывать функцию базового класса, которую я переопределяю. в java есть синтаксис <code>super.funcname()</code>. возможно ли это в c++?</p>

<p>синтаксис c++ выглядит так:</p><pre><code>class bar : public foo { // ... void printstuff() { foo::printstuff(); // calls base class' function } }; </code></pre>

<p>да,</p><pre><code>class bar : public foo { ... void printstuff() { foo::printstuff(); } }; </code></pre><p>он такой же, как <code>super</code> в java, за исключением того, что он позволяет вызывать реализации из разных баз, когда у вас есть множественное наследование.</p><pre><code>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(); } }; </code></pre>

<p>иногда вам нужно вызвать реализацию базового класса, когда вы не в производной функции ... это все еще работает:</p><pre><code>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 trippy but it works assert(-1 == x->base::foo()); return 0; } </code></pre>

<p>на всякий случай, если вы делаете это для многих функций в вашем классе:</p><pre><code>class foo { public: virtual void f1() { // ... } virtual void f2() { // ... } //... }; class bar : public foo { private: typedef foo super; public: void f1() { super::f1(); } }; </code></pre><p>это может сэкономить немного времени, если вы хотите переименовать foo.</p>

<p>если вы хотите вызвать функцию базового класса из ее производного класса, вы можете просто вызвать внутри переопределенной функции упоминание имени базового класса (например,<strong> foo :: printstuff () </strong>).</p><p>код идет здесь</p><pre><code>#include <iostream> using namespace std; class foo { public: int x; virtual void printstuff() { cout<<"base foo printstuff called"<<endl; } }; class bar : public foo { public: int y; void printstuff() { cout<<"derived bar printstuff called"<<endl; foo::printstuff();/////also called the base class method } }; int main() { bar *b=new bar; b->printstuff(); } </code></pre><p>опять же, вы можете определить во время выполнения, какую функцию вызывать, используя объект этого класса (производный или базовый). но для этого необходимо, чтобы ваша функция в базовом классе была помечена как виртуальная.</p><p>код ниже</p><pre><code>#include <iostream> using namespace std; class foo { public: int x; virtual void printstuff() { cout<<"base foo printstuff called"<<endl; } }; class bar : public foo { public: int y; void printstuff() { cout<<"derived bar printstuff called"<<endl; } }; int main() { foo *foo=new foo; foo->printstuff();/////this call the base function foo=new bar; foo->printstuff(); } </code></pre>

<p>проверь это...</p><pre><code>#include <stdio.h> 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::string s; std::cout << "press any key to exit" << std::endl; std::cin >> s; return 0; } </code></pre><p>результат</p><pre><code>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 </code></pre><p>лучший способ - использовать<strong> base :: function </strong>как говорят @sth</p>

<p>да, вы можете назвать это. синтаксис c++ для вызова функции родительского класса в дочернем классе </p><pre><code>class child: public parent { // ... void methodname() { parent::methodname(); // calls parent class' function } }; </code></pre><p>узнайте больше о функции <a href="https://www.codeslehrer.com/function-overriding-c/">переопределение</a> .</p>