【C++历险记】国庆专辑---探索多态迷宫的代码之旅
温馨提示:这篇文章已超过413天没有更新,请注意相关的内容是否还可用!
本篇目录
- 一、什么是多态?
- 二、多态的定义及其实现
- 2.1多态构成的条件
- 2.2虚函数
- 2.3虚函数的重写
- 2.3.1析构函数的重写
- 2.4C++11 override 和 final
- 2.5重载、覆盖(重写)、隐藏(重定义)的对比
- 2.6为什么不能是子类的指针或者引用呢?
- 2.7为什么不能是父类对象呢?
- 2.8子类中为什么要对付类的虚函数进行重写?
- 三、多态的实现原理
- 3.1虚函数表
- 3.2派生类中的虚函数表
- 3.3探索内存中的虚函数表
- 3.4多态实现的原理
- 3.5动态绑定与静态绑定
- 四、单继承和多继承关系的虚函数表
- 4.1多继承中的虚函数表
- 4.2菱形继承、菱形虚拟继承
- 4.2.1普通菱形继承
- 4.2.2菱型虚拟继承
- 五、抽象类
- 5.1概念
- 5.2接口继承和实现继承
- 六、问答环节
- 七、常见面试题
- 🍀小结🍀
🎉博客主页:.小智
🎉欢迎关注:👍点赞🙌收藏✍️留言
🎉系列专栏:C++终极篇
🎉代码仓库:小智的代码仓库
一、什么是多态?
多态多态顾名思义就是多种形态,比如我们要完成某一件事情,不同的对象去完成,我们产生的结果是不一样的。
举个栗子我们平时的买火车票,就有这几种分类:
- 成人票----全价
- 学生票----半价
- 军人----优先
再来举个栗子:支付宝年底经常会做诱人的扫红包-支付-给奖励金的活动。那么大家想想为什么有人扫的红包又大又新鲜8块、10块…,而有人扫的红包都是1毛,5毛…。其实这背后也是一个多态行为。支付宝首先会分析你的账户数据,比如你是新用户、比如你没有经常支付宝支付等等,那么你需要被鼓励使用支付宝,那么就你扫码金额 =random()%99;比如你经常使用支付宝支付或者支付宝账户中常年没钱,那么就不需要太鼓励你去使用支付宝,那么就你扫码金额 = random()%1;总结一下:同样是扫码动作,不同的用户扫得到的不一样的红包,这也是一种多态行为。
ps:支付宝红包问题纯属瞎编,大家仅供娱乐。
二、多态的定义及其实现
2.1多态构成的条件
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价。
那么在继承中要构成多态还有两个条件:
- 必须通过基类的指针或者引用调用虚函数
- 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写
class Person { public: virtual void BuyTicket() { cout public: virtual void BuyTicket() { cout people.BuyTicket(); } int main() { Person P; Func(P); Student S; Func(S); } }; 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() { cout public: ~Student() { cout Person* P = new Person;//new一个person对象 delete P; P = new Student;//delete之后再new一个student对象 delete P; } public: virtual void BuyTicket() { cout public: virtual void BuyTicket() { cout p.BuyTicket(); } int main() { Person ps; Student st; Func(st); return 0; } public: virtual void Func1() { cout Base b; cout public: virtual void Func1() { cout cout cout public: virtual void Func1() { cout Base b; Derive d; return 0; } Base b; Derive d; int a = 0; printf("栈:%p\n", &a); static int b1 = 0; printf("静态区:%p\n", &b1); int* p = new int; printf("堆:%p\n", p); const char* str = "hello world"; printf("常量区:%p\n", str); printf("虚表1:%p\n", *((int*)&b)); printf("虚表2:%p\n", *((int*)&d)); return 0; } public: virtual void BuyTicket() { cout cout cout public: virtual void BuyTicket() { cout //_b++; cout Person ps; Student st; return 0; } for (size_t i = 0; table[i] != nullptr; i++) { printf("[%d]:%p-", i, table[i]); FUNC_PTR f = table[i]; f();//调用函数 } printf("\n"); } int main() { Person ps; Student st; int vft1 = *((int*)&ps); PrintVFT((FUNC_PTR*)vft1); int vft2 = *((int*)&st); PrintVFT((FUNC_PTR*)vft2); return 0; } public: virtual void BuyTicket() { cout public: virtual void BuyTicket() { cout p.BuyTicket(); } int main() { Person Mike; Func(Mike); Student Johnson; Func(Johnson); return 0; } public: virtual void func1() { cout cout public: virtual void func1() { cout cout public: virtual void func1() { cout cout for (size_t i = 0; table[i] != nullptr; i++) { printf("[%d]:%p-", i, table[i]); FUNC_PTR f = table[i]; f(); } printf("\n"); } int main() { Derive d; int vft1 = *((int*)&d); Base2* ptr = &d; int vft2 = *((int*)ptr); PrintVFT((FUNC_PTR*)vft1); PrintVFT((FUNC_PTR*)vft2); return 0; } public: virtual void func1() { cout cout public: virtual void func1() { cout cout public: virtual void func1() { cout cout public: virtual void func1() { cout cout cout D d; d.B::_a = 1; d.C::_a = 2; d._b = 3; d._c = 4; d._d = 5; return 0; } public: virtual void func1() { cout cout public: virtual void func1() { cout cout public: virtual void func1() { cout cout public: virtual void func1() { cout cout cout cout printf("vTable[%d]:0X%p---------", i, vTable[i]); VFPTR f = vTable[i]; f(); } cout A a; cout public: virtual void Drive() const = 0; }; class Benz : public Car { public: virtual void Drive() const { cout public: virtual void Drive() const { cout car.Drive(); } int main() { Benz be; Advantages(be); Bmw bm; Advantages(bm); } 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; }
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!


