C++必修:深入探索多态的奥秘
✨✨ 欢迎大家来到贝蒂大讲堂✨✨
🎈🎈养成好习惯,先赞后看哦~🎈🎈
所属专栏:C++学习
贝蒂的主页:Betty’s blog
前言需知:
本文中的代码及解释都是在vs2022下的x86程序中,涉及的指针都是4bytes。如果要其他平台下,部分代码需要改动。比如:如果是x64程序,则需要考虑指针是8bytes问题等等。
1. 多态的引入
1.1. 多态的概念
通俗来说,多态就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。举一个简单的例子:
当我们去买票时,普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票。普通人,学生,军人虽然都属于人这类整体,但是在进行买票这个行为时却会发生不同的状态。这就是一种典型的多态行为。
1.2. 多态的定义
在 C++ 中,多态指的是通过基类的指针或引用,在运行时能够调用派生类中实现的同名函数,从而表现出不同的行为。而构成多态一定要满足两个条件:
- 必须通过基类的指针或者引用调用虚函数。
- 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
下面是一个简单的多态调用:
class Person { public: virtual void BuyTicket() //虚函数 { cout public: virtual void BuyTicket()//虚函数重写 { cout p.BuyTicket(); } int main() { Person ps; Student st; Func(ps); Func(st); return 0; } public: virtual void BuyTicket() { cout public: virtual void BuyTicket() //虚函数 { cout public: virtual void BuyTicket() //虚函数重写 { cout }; class B :public A{};//不同的继承 class Person { public: virtual A* f() { return new A; } }; class Student : public Person { public: virtual B* f() //协变 { return new B; } }; public: //~Person() virtual ~Person() { cout public: virtual ~Student() //构成重写 { cout Person* p1 = new Person; Person* p2 = new Student; delete p1; delete p2; return 0; } public: virtual void Drive() = 0;//纯虚函数 }; class Benz :public Car { public: virtual void Drive() { cout public: virtual void Drive() { cout Car* pBenz = new Benz; pBenz-Drive(); Car* pBMW = new BMW; pBMW-Drive(); } public: virtual void Func1() { cout public: virtual void Func1() { cout }; public: virtual void Func1() { cout cout cout public: virtual void Func1() { cout cout for (int i = 0; table[i] != nullptr; i++) { printf("第%d个虚函数表的地址为:%p-", i+1, table[i]); table[i]();//通过函数指针调用函数 } } int main() { Base b; Derive d; //需要取_vfptr的前4个字节(当然不同平台实现也有区别) printVFTable((VF_PTR*)(*(int*)&b)); cout public: virtual void func1() { cout cout public: virtual void func1() { cout cout public: virtual void func1() { cout cout for (int i = 0; table[i] != nullptr; i++) { printf("第%d个虚函数表的地址为:%p-", i + 1, table[i]); table[i]();//通过函数指针调用函数 } } int main() { Derive d; printVFTable((VF_PTR*)(*(int*)&d)); cout Derive d; Base1* ptr1 = &d; Base2* ptr2 = &d; ptr1-func1(); ptr2-func1(); return 0; } public: virtual void func1() {} public: int _a; }; class B : virtual public A { public: virtual void func1() {} public: int _b; }; class C : virtual public A { public: virtual void func1() {} public: int _c; }; class D : public B, public C { public: //必须自己重写func1 virtual void func1() {} int _d; }; public: virtual void func1() {} public: int _a; }; class B : virtual public A { public: virtual void func1() {} virtual void func2() {} public: int _b; }; class C : virtual public A { public: virtual void func1() {} virtual void func3() {} public: int _c; }; class D : public B, public C { public: //必须自己重写func1 virtual void func1() {} int _d; }; public: virtual void func(int val = 1) { std::cout func(); } }; class B : public A { public: void func(int val = 0) { std::cout B* p = new B; p-test();//输出?? return 0; }
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。