【C++奇遇记】C++中的进阶知识(多态(一))

[复制链接]
发表于 2025-9-30 07:13:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
🎬 博客主页:博主链接
🎥 本文由 M malloc 原创,首发于 CSDN🙉
🎄 学习专栏保举:LeetCode刷题集 数据库专栏 初阶数据结构
🏅 接待点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📆 未来很长,值得我们尽力奔赴更优美的生存✨
  




😇本章详情

   🐤本篇文章将继承教学C++的多态干系的知识
  😇多态的前情先容

📝多态的概念

   多态(polymorphism)的概念:平凡来说,就是多种形态。
  
运⾏时多态,具体点就是去完成某个⾏为(函数),可以传差异的对象就会完成差异的⾏为,就到达多种形态。比方动物叫是一个举动(函数),传猫对象已往,就是喵喵,传狗对象已往就是汪汪

😇多态的界说及实现

📝多态的构成条件


多态是⼀个继承关系的下的类对象,去调⽤同⼀函数,产⽣了差异的⾏为。⽐如Student继承了Person。Person对象买票全价,Student对象优惠买票。

实现多态的两个告急条件

  • 必须是基类的指针大概引⽤调⽤虚函数
  • 被调⽤的函数必须是虚函数,而且完成了虚函数重写/覆盖。
阐明
   要实现多态结果,第一必须是基类的指针大概引用,由于只有基类的指针或引用才气既指向基类对象又指向派生类对象;第二派生类必须对基类的虚函数完成了重写/覆盖,重写大概覆盖了,基类和派生类之间才气有差异的函数,多态的差异形态结果才气到达。
  
📝 虚函数的重写/覆盖

   虚函数的重写/覆盖:派⽣类中有⼀个跟基类完全雷同的虚函数(即派⽣类虚函数与基类虚函数的返回值范例、函数名字、参数列表完全雷同),称派⽣类的虚函数重写了基类的虚函数。
  
   注意:在重写基类虚函数时,派⽣类的虚函数在不加virtual关键字时,固然也可以构成重写(由于继承后基类的虚函数被继承下来了在派⽣类仍旧保持虚函数属性),但是该种写法不是很规范,不发起如许利用,不外在测验选择题中,常常会故意买这个坑,让你判定是否构成多态。
  1. class Person {
  2. public:
  3. virtual void BuyTicket() { cout << "买票-全价" << endl; }
  4. };
  5. class Student : public Person {
  6. public:
  7.         virtual void BuyTicket() { cout << "买票-打折" << endl; }
  8. };
  9. void Func(Person* ptr)
  10. {
  11.         // 这⾥可以看到虽然都是Person指针Ptr在调⽤BuyTicket
  12.         // 但是跟ptr没关系,⽽是由ptr指向的对象决定的。
  13.         ptr->BuyTicket();
  14. }
  15. int main()
  16. {
  17.         Person ps;
  18.         Student st;
  19.         Func(&ps);
  20.         Func(&st);
  21.         return 0;
  22. }
复制代码

   在上述代码中,起首我们写了一个Person基类,内里界说了一个虚函数BuyTicket,又创建了一个门生派生类继承Person基类,而且重写了BuyTicket成员函数。此时我们想要调用试一下,于是我们写了一个Func函数,参数列表必须是基类的指针大概引用。
  
📝析构函数的重写

基类的析构函数为虚函数,此时派⽣类析构函数只要界说,⽆论是否加virtual关键字,都与基类的析 构函数构成重写,固然基类与派⽣类析构函数名字差异看起来不符合重写的规则,实际上编译器对析 构函数的名称做了特殊处置惩罚,编译后析构函数的名称统⼀处置惩罚成destructor,以是基类的析构函数加了 vialtual修饰,派⽣类的析构函数就构成重写。
代码实现
  1. class A
  2. {
  3. public:
  4.         virtual ~A()
  5.         {
  6.                 cout << "~A()" << endl;
  7.         }
  8. };
  9. class B : public A {
  10. public:
  11.         ~B()
  12.         {
  13.                 cout << "~B()->delete:" << _p << endl;
  14.                 delete _p;
  15.         }
  16. protected:
  17.         int* _p = new int[10];
  18. };
  19. // 只有派⽣类Student的析构函数重写了Person的析构函数,下⾯的delete对象调⽤析构函数,才能
  20. // 构成多态,才能保证p1和p2指向的对象正确的调⽤析构函数。
  21. int main()
  22. {
  23.         A* p1 = new A;
  24.         A* p2 = new B;
  25.         delete p1;
  26.         delete p2;
  27.         return 0;
  28. }
复制代码
  在上述代码中,如果基类A中的析构函数,不加上virtual的话,A 和B 是不构成重写的,此时在对对象举行析构的时间是会造成内存走漏的,delete p2是只会调用A的析构函数的,如许就会导致内存走漏的缘故原由,由于~B()在开释资源
  

📃怎样巩固学习

   提示:在学习的过程中,我们必要先自行举行思考,而且多去阅读一些大佬的册本,俗话说的好,册本是人类进步的蹊径!
  📃本文小结


  • 这只是继承中的一小部分知识,山高路远,我们下期再见啦!!!!
   好啦本日的分享到这里就竣事啦,我是爱你们的M malloc渴望可以资助到你们噢,末了别忘记三连啦!!
  


回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表