C++是一门难学易用的语言,如果没有深刻理解一些基本概念,编写的代码就会经常出现一些奇怪的问题。
下面这个问题就是我当初学习C++ OOP概念时遇到的,也是我在工作中遇到的,这个问题没有复杂的技巧,也不是“茴香豆的茴有几种写法”之类的死板教条,只要你基础扎实,一定能回答出来。
问题很简单,我们都知道,C++中基类指针可以指向派生类对象,那么下面的代码是否正确?
#include <iostream> using namespace std;
class Base { public: int a;
Base(int a): a(a) {} };
class Derived: public Base { public: Derived(int a): Base(a) {}
void Print() { cout << "a: " << a << endl; } };
int main() { Derived d(100); Base* pb; pb = &d; pb->Print();
return 0; }
|
有啥想法了吗?
如果没有,编译时会输出下面信息,能看出什么端倪了吗?
$ g++ test.cpp -o test test.cpp: In function ‘int main()’: test.cpp:27: error: ‘class Base’ has no member named ‘Print’
|
提示错误:基类‘Base’没有成员的名字是‘Print’,我们预想通过基类指针去调用派生类的函数成员。
“如果调用非虚函数,则无论实际对象是什么类型,都执行基类类型所定义的函数。”
–《C++ Primer》第四版中文版480页
没错,如果要想通过基类指针调用派生类的函数成员,得将函数定义成虚函数,像下面这样:
#include <iostream> using namespace std;
class Base { public: int a;
Base(int a): a(a) {} virtual ~Base() {} virtual void Print() {} };
class Derived: public Base { public: Derived(int a): Base(a) {}
virtual void Print() { cout << "a: " << a << endl; } };
int main() { Derived d(100); Base* pb; pb = &d; pb->Print();
return 0; }
|
$ g++ test.cpp -o test $ ./test a: 100
|
这里涉及到C++ OOP的多态概念,希望你通过此问题对C++多态有更深入的理解,如果有兴趣,还可以再研究下C++多态是怎么实现的,什么是虚函数表,相信你会有大彻大悟的感觉。