Can I call a base class's virtual function if I'm overriding it?
假设我有这样的类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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; } }; |
正如代码中所注释的,我希望能够调用我要重写的基类函数。在爪哇,有EDOCX1 2语法。在C++中这是可能的吗?
C++语法是这样的:
1 2 3 4 5 6 7 | class Bar : public Foo { // ... void printStuff() { Foo::printStuff(); // calls base class' function } }; |
对,
1 2 3 4 5 6 7 8 9 | class Bar : public Foo { ... void printStuff() { Foo::printStuff(); } }; |
它与爪哇中的EDCOX1(0)相同,除了它允许在多个继承时调用来自不同基的实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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(); } }; |
有时,当您不在派生函数中时,您需要调用基类的实现…它仍然有效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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; } |
以防万一你在你的课堂上做了很多功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Foo { public: virtual void f1() { // ... } virtual void f2() { // ... } //... }; class Bar : public Foo { private: typedef Foo super; public: void f1() { super::f1(); } }; |
如果您想重命名foo,这可能会节省一些编写时间。
如果要从派生类调用基类的函数,只需在重写函数内部调用提到的基类名称(如foo::printstuff())。
代码在这里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #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(); } |
同样,您可以在运行时使用该类(派生或基)的对象确定要调用的函数。但这要求您的基类函数必须标记为虚拟。
下面的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #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(); } |
是的,你可以叫它。调用子类中的父类函数的C++语法
1 2 3 4 5 6 7 | class child: public parent { // ... void methodName() { parent::methodName(); // calls Parent class' function } }; |
了解有关函数重写的更多信息。
检查这个…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <stdio.h> class Base { public: virtual void gogo(int a) { printf(" Base :: gogo (int) "); }; virtual void gogo1(int a) { printf(" Base :: gogo1 (int) "); }; void gogo2(int a) { printf(" Base :: gogo2 (int) "); }; void gogo3(int a) { printf(" Base :: gogo3 (int) "); }; }; class Derived : protected Base { public: virtual void gogo(int a) { printf(" Derived :: gogo (int) "); }; void gogo1(int a) { printf(" Derived :: gogo1 (int) "); }; virtual void gogo2(int a) { printf(" Derived :: gogo2 (int) "); }; void gogo3(int a) { printf(" Derived :: gogo3 (int) "); }; }; 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; } |
输出
1 2 3 4 5 6 7 8 9 10 11 | 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 |
最好的方法是使用base::函数,如say@sth