C++ 虚函数表与多态 —— 多态的实现:虚函数 & 虚函数表

 
 C++面试经常会被问的问题就是多态原理。如果对C++面向对象本质理解不是特别好,问到这里就会崩。 下面从基本到原理,详细说说多态的实现:虚函数 & 虚函数表。
 

1. 多态的本质:

形式上,使用统一的父类指针做一般性处理。但是实际执行时,这个指针可能指向子类对象。

形式上,原本调用父类的方法,但是实际上会调用子类的同名方法。

坦白的说,多态就是为了通过使用父类的指针,能够调用父类与子类他们各自的方法。如果不使用多态,用父类指针调用子类的方法时,也会调用到父类的方法。

具体参考:C++ 虚函数表与多态 —— 多态的简单用法

【注意】

程序执行时,父类指针指向父类对象,或子类对象时,在形式上是无法分辨的。只有通过多态机制,才能执行真正对应的方法。

2. 虚函数:

在父类的方法函数前,增加 virtual 便可以使这个函数变为虚函数,如:

需要注意一点,例子用的是内联函数,封装到外部时,具体方法实现前不用加 virtual,用了会出错。

 1 class Father
 2 {
 3 public:
 4     virtual void play()              //父类的 play() 方法前增加 virtual 关键字,这个函数便成为了虚函数
 5     {
 6         std::cout << "这是个父类的play" << std::endl;
 7     }
 8 };
 9 
10 class Son : public Father
11 {
12 public:
13     void play()
14     {
15         std::cout << "这是个子类的Play" << std::endl;
16     }
17 };

3. 虚函数的继承:

如果某个成员函数被声明为虚函数,那么它的子类【派生类】中所继承的成员函数,也会变为虚函数。

如果在子类中重写这个虚函数,可以不用再写 virtual ,但是仍建议写上 virtual,这样会使代码更可读,如13行:

 1 class Father
 2 {
 3 public:
 4     virtual void play()                                        //父类的 play() 方法前增加 virtual 关键字,这个函数便为虚函数
 5     {
 6         std::cout << "这是个父类的play" << std::endl;
 7     }
 8 };
 9 
10 class Son : public Father
11 {
12 public:
13     virtual void play()                                        //派生类继承的虚函数前,可以不加 virtual,但加上会使代码更加可读
14     {
15         std::cout << "这是个子类的Play" << std::endl;
16     }
17 };

4. 虚函数的原理:

虚函数的原理是通过虚函数表来实现的,虚函数表是编译器搞出来的东西他并不存在与对象中,先看下边代码:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Father
 5 {
 6 public:
 7     virtual void func_1() { cout << "Father::func_1" << endl; }
 8     virtual void func_2() { cout << "Father::func_2" << endl; }
 9     virtual void func_3() { cout << "Father::func_3" << endl; }
10     11 };
12 
13 int main(void)
14 {
15     Father father_1;        //虚函数表就保存在这个 father 对象里边
16 
17     cout << "sizeof(father_1)=="<< sizeof(father_1) << endl;
18 
19 }

运行后打印一下,看看 father 对象占用多大内存空间。

运行结果:sizeof(father_1)==4

3个虚函数为什么只占4个字节?因为他存的是一张表,他没有占用对象的内存空间,对象中只存在一个指针,指向一个虚函数表,如下方示意图,不管你有多少个虚函数,他都在虚函数表里:

    

===========================================================================================================================

猜你喜欢

转载自www.cnblogs.com/CooCoChoco/p/12549792.html