希望十一月对我好一点:C++之多态(2)--多态的原理(部分)

多态的原理

在这里插入图片描述

虚函数表指针

下⾯编译为32位程序的运⾏结果是什么()

A. 编译报错 B.运⾏报错C.8 D.12

class Base
 {
 public:
 virtual void Func1()
 {
 cout << "Func1()" << endl;
 }
 protected:
 int _b = 1;
 char _ch = 'x';
 };
 int main()
 {
      Base b;
 cout << sizeof(b) << endl;
 return 0;
 }

上⾯题⽬运⾏结果12bytes,除了_ b和_ch成员,还多⼀个__vfptr放在对象的前⾯(注意有些平台可能 会放到对象的最后⾯,这个跟平台有关),对象中的这个指针我们叫做虚函数表指针(v代表virtual,f代 表function)。⼀个含有虚函数的类中都⾄少都有⼀个虚函数表指针,因为⼀个类所有虚函数的地址要 被放到这个类对象的虚函数表中,虚函数表也简称虚表。

多态的原理

在这里插入图片描述

多态是如何实现的

从底层的⻆度Func函数中ptr->BuyTicket(),是如何作为ptr指向Person对象调⽤Person::BuyTicket, ptr指向Student对象调⽤Student::BuyTicket的呢?满⾜多态条件后,底层 不再是编译时通过调⽤对象确定函数的地址,⽽是运⾏时到指向的对象的虚表中确定对应的虚函数的 地址,这样就实现了指针或引⽤指向基类就调⽤基类的虚函数,指向派⽣类就调⽤派⽣类对应的虚函 数。

class Person {
    
    
 public:
 virtual void BuyTicket() {
    
     cout << "买票全价" << endl; }
 };
 class Student : public Person {
    
    
 public:
 virtual void BuyTicket() {
    
     cout << "买票打折" << endl; }
 };
 class Soldier: public Person {
    
    
 public:
 virtual void BuyTicket() {
    
     cout << "买票优先" << endl; }
 };
 void Func(Person* ptr)
 {
    
    
 // 这⾥可以看到虽然都是Person指针Ptr在调⽤BuyTicket 
// 但是跟ptr没关系,⽽是由ptr指向的对象决定的。
 
ptr->BuyTicket();
 }
 
 int main()
 {
    
    
 // 其次多态不仅仅发⽣在派⽣类对象之间,多个派⽣类继承基类,重写虚函数后
 
// 多态也会发⽣在多个派⽣类之间。
Person ps;
 Student st;
 Soldier sr;
Func(&ps);
 Func(&st);
 Func(&sr);
 return 0;
 }

猜你喜欢

转载自blog.csdn.net/Mr_Xuhhh/article/details/143450940