C++学习之对多态的理解

最近学习C++多态及子类内存结构,有一些理解与看法,记录下来

1.多态产生,虚函数,虚函数指针,虚函数表

这一部分不详细描述,个人参考的书籍是Siddhartha Rao的<21天学通C++>的第11章:多态

了解了编译器利用虚函数表与对象的虚函数指针来实现多态的机制

觉得比较好的文章就记在下面

【转】:https://blog.csdn.net/jiangnanyouzi/article/details/3720807

2.自己的一些思考

Siddhartha Rao:在函数声明中, virtual 意味着当基类指针指向派生对象时,通过它可调用派生类的相应函数

实际上不管有没有出现virtual关键字,基类指针指向子类对象时都发生了一次隐式的强转,即是说基类指针变量的值仍然与子类对象地址的值相同(子类对象第一个字节的地址编号),但是偏移量不同。

所以在没有virtual关键字的时候经过隐式强转,基类指针变量实际指向的是一个基类的对象实例,那么调用对应的方法等同于调用基类实例的方法

然而在有virtual关键字的时候也要经过隐式强转,由于编译器会给子类对象分配一个虚函数表指针,虽然基类指针指向的是一个基类对象实例,但是虚函数指针所指向的虚函数表中的函数却是子类的函数,实现了基类指针调用派生类函数

自己验证的代码如下:

root@ubuntu:/lianxi/lianxi_c++/duotai# g++ 11.1\ InvokingSwimUsingFishPtr.cpp 
root@ubuntu:/lianxi/lianxi_c++/duotai# ./a.out
Tuna swims!
lets see InputFish->Swim()
Fish swims!

lets see p->Swim()
Tuna swims!
root@ubuntu:/lianxi/lianxi_c++/duotai# 
  1 #include <iostream>
  2 #include <stdio.h>
  3 
  4 using namespace std;
  5 
  6 class Fish
  7 {
  8 public:
  9    void Swim()
 10    {
 11       cout << "Fish swims!" << endl;
 12    }
 13 };
 14 
 15 class Tuna:public Fish
 16 {
 17 public:
 18    void Swim()
 19    {
 20       cout << "Tuna swims!" << endl;
 21    }
 22 };
 23 
 24 void MakeFishSwim(Fish* InputFish)
 25 {
 26    printf("lets see InputFish->Swim()\n");
 27    InputFish->Swim();//Fish swims!
 28    putchar(10);
 29    printf("lets see p->Swim()\n");
 30    Tuna* p = NULL;
 31    p = (Tuna*)(InputFish);
 32    p->Swim();//Tuna swims!
 33    return;
 34 }
 35 
 36 int main() 
 37 {  
 38    Tuna myDinner;
 39    
 40    myDinner.Swim();
 41    
 42    MakeFishSwim(&myDinner);
 43    
 44    return 0;
 45 }

猜你喜欢

转载自blog.csdn.net/liaojunwu/article/details/85032631