C++[多态]

打印 上一主题 下一主题

主题 1025|帖子 1025|积分 3075

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

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

x
  1. 2023-3-14首次编辑
复制代码

  
Unit 8:多态

一.概念

   同一个操作作用域不同的对象,可以有不同的解释,会产生不同的效果
  1. #define _CRT_SECIRE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. class People
  5. {
  6. public:
  7.         virtual void Mypro()
  8.         {
  9.                 //虚函数
  10.         }
  11. };
  12. class xishi :public People
  13. {
  14. public:
  15.         //重写父类的虚函数
  16.         virtual void Mypro()
  17.         {
  18.                 cout << "约西施" << endl;
  19.         }
  20. };
  21. class wangzhaojun :public People
  22. {
  23. public:
  24.         //重写父类的虚函数
  25.         virtual void Mypro()
  26.         {
  27.                 cout << "约王昭君" << endl;
  28.         }
  29. };
  30. class diaochan :public People
  31. {
  32. public:
  33.         //重写父类的虚函数
  34.         virtual void Mypro()
  35.         {
  36.                 cout << "约貂蝉" << endl;
  37.         }
  38. };
  39. class yangguifei :public People
  40. {
  41. public:
  42.         //重写父类的虚函数
  43.         virtual void Mypro()
  44.         {
  45.                 cout << "约杨贵妃" << endl;
  46.         }
  47. };
  48. //2.同一个操作
  49. void doLogin(People* pro)
  50. {
  51.         pro->Mypro(); //3.产生不同的效果
  52. }
  53. void test()
  54. {
  55.         People* pro = NULL;
  56.         pro = new xishi;
  57.         doLogin(pro); //1.不同对象
  58.         delete pro;
  59.         pro = new wangzhaojun;
  60.         doLogin(pro); //1.不同对象
  61.         delete pro;
  62.         pro = new diaochan;
  63.         doLogin(pro); //1.不同对象
  64.         delete pro;
  65.         pro = new yangguifei;
  66.         doLogin(pro); //1.不同对象
  67.         delete pro;
  68. }
  69. int main()
  70. {
  71.         test();
  72.         system("pause");
  73.         return 0;
  74. }
复制代码
  作用:
  

  • 可以解决项目中的紧耦合问题,提供步伐的可扩展性
  • 应用步伐不必为每一个子类的功能调用编写代码,只需要对抽象的父类进行处理
  
  多态发生的条件:
  

  • 有继续
  • 重写父类的虚函数
  • 父类指针指向子类对象
  二.多态的实现原理

  1. #define _CRT_SECIRE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. class Animal
  5. {
  6. public:
  7.         virtual void speak()
  8.         {
  9.                 cout << "Animal speak()" << endl;
  10.         }
  11. };
  12. class Dog :public Animal
  13. {
  14. public:
  15.         virtual void speak()
  16.         {
  17.                 cout << "Dog speak()" << endl;
  18.         }
  19. };
  20. void test()
  21. {
  22.         cout << sizeof(Animal) << endl;
  23.         Animal* animal = new Dog;
  24.         animal->speak();
  25. }
  26. int main()
  27. {
  28.         test();
  29.         system("pause");
  30.         return 0;
  31. }
复制代码
三.纯虚函数和抽象类

  1. #define _CRT_SECIRE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. //1.依赖倒转:
  5. //  业务层依赖抽象层,实现层依赖抽象层
  6. //抽象层
  7. class rule1
  8. {
  9. public:
  10.         virtual int getnum(int a, int b)
  11.         {
  12.                 return 0;
  13.         }
  14. };
  15. //实现层
  16. class plus_rule :public rule1
  17. {
  18.         //重写父类的虚函数,依赖抽象层
  19.         virtual int getnum(int a, int b)
  20.         {
  21.                 return a + b;
  22.         }
  23. };
  24. //业务层
  25. int doLogin(rule1* cal)
  26. {
  27.         int a = 10;
  28.         int b = 20;
  29.         int ret = cal->getnum(a, b); //依赖抽象层
  30.         return ret;
  31. }
  32. //2.开闭原则:
  33. //  对修改源代码关闭,对扩展新功能开发
  34. class miux_rule :public rule1
  35. {
  36. public:
  37.         //扩展新功能
  38.         virtual int getnum(int a, int b)
  39.         {
  40.                 return a - b;
  41.         }
  42. };
  43. void test1()
  44. {
  45.         rule1* r = NULL;
  46.         r = new plus_rule;
  47.         cout << doLogin(r) << endl;
  48.         delete r;
  49.         r = new miux_rule;
  50.         cout << doLogin(r) << endl;
  51.         delete r;
  52. }
  53. //3.纯虚函数:
  54. class rule2
  55. {
  56. public:
  57.         virtual int getnum(int a, int b) = 0;
  58. };
  59. //4.抽象类:
  60. //  A.有纯虚函数的类叫抽象类,不能实例化对象
  61. //  B.如果子类继承抽象类,子类必须实现抽象类的所有纯虚函数,不然子类也变为抽象类
  62. class Maker
  63. {
  64. public:
  65.         virtual void func1() = 0;
  66.         virtual void func2() = 0;
  67. };
  68. class Son :public Maker
  69. {
  70. public:
  71.         virtual void func1()
  72.         {
  73.         }
  74.         virtual void func2()
  75.         {
  76.         }
  77. };
  78. void test2()
  79. {
  80.         //Maker a; //err
  81.         Son s;
  82. }
  83. int main()
  84. {
  85.         test1();
  86.         test2();
  87.         system("pause");
  88.         return 0;
  89. }
复制代码
四.接口的定义

   

  • 将内部实现细节封装起来
  • 外部用户通过预留的接口可以利用接口的功能
  • 而不需要知道内部具体细节
  
  

  • C++中,通过类实现面向对象的编程
  • 而在基类中只给出虚函数的声明
  • 然后在派生类中通过实现纯虚函数的具体定义的方式,实现接口
  • 不同的派生类实现接口的方式也不尽相同
  1. #define _CRT_SECIRE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. //抽象类
  5. class Father
  6. {
  7. public:
  8.         //接口的声明
  9.         virtual void func1() = 0;
  10.         virtual void func2(int a) = 0;
  11.         virtual void func3(int a, int b) = 0;
  12. };
  13. class Son :public Father
  14. {
  15. public:
  16.         //接口的实现
  17.         virtual void func1()
  18.         {
  19.         }
  20.         virtual void func2(int a)
  21.         {
  22.         }
  23.         virtual void func3(int a, int b)
  24.         {
  25.         }
  26. };
  27. int main()
  28. {
  29.         system("pause");
  30.         return 0;
  31. }
复制代码
五.模板方法模式

   在类中确定好函数的调用顺序
  1. #define _CRT_SECIRE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. class Drink
  5. {
  6. public:
  7.         //烧水
  8.         virtual void Boil() = 0;
  9.         //冲泡
  10.         virtual void Brew() = 0;
  11.         //倒入杯中
  12.         virtual void PourInCup() = 0;
  13.         //加点辅料
  14.         virtual void addSonm() = 0;
  15.         //模板方法:把调用函数的顺序确定下来
  16.         void func()
  17.         {
  18.                 Boil();
  19.                 Brew();
  20.                 PourInCup();
  21.                 addSonm();
  22.         }
  23. };
  24. int main()
  25. {
  26.         system("pause");
  27.         return 0;
  28. }
复制代码
六.虚析构函数和纯虚析构函数

   虚析构函数:
  

  • 为了解决基类指针指向派生类对象,并用基类指针释放派生类对象
  
  纯虚析构函数:
  

  • 有纯虚析构函数的类是抽象类,不能实例化对象
  1. #define _CRT_SECIRE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. class Animal
  5. {
  6. public:
  7.         Animal()
  8.         {
  9.                 cout << "Animal的构造" << endl;
  10.         }
  11.         A.虚析构函数:会调用子类的析构函数
  12.         //virtual ~Animal()
  13.         //{
  14.         //        cout << "Animal的析构" << endl;
  15.         //}
  16.         //B.纯虚析构函数:需要在类外实现
  17.         virtual ~Animal() = 0;
  18. };
  19. Animal::~Animal()
  20. {
  21.         cout << "Animal的析构" << endl;
  22. }
  23. class Son :public Animal
  24. {
  25. public:
  26.         Son()
  27.         {
  28.                 cout << "Son的构造函数" << endl;
  29.                 pName = new char[64];
  30.                 memset(pName, 0, 64);
  31.                 strcpy(pName, "如花");
  32.         }
  33.         ~Son()
  34.         {
  35.                 cout << "Son的析构函数" << endl;
  36.                 if (pName!=NULL)
  37.                 {
  38.                         delete[] pName;
  39.                         pName = NULL;
  40.                 }
  41.         }
  42. public:
  43.         char* pName;
  44. };
  45. void test()
  46. {
  47.        
  48.         //Animal a; //纯虚析构函数是抽象类,不能实例化对象
  49.         Animal* animal = new Son;
  50.         delete animal;
  51. }
  52. int main()
  53. {
  54.         test();
  55.         system("pause");
  56.         return 0;
  57. }
复制代码
七.父类引用子类对象

  1. #define _CRT_SECIRE_NO_WARNINGS
  2. #include <iostream>
  3. using namespace std;
  4. class Animal
  5. {
  6. public:
  7.         virtual void speak()
  8.         {
  9.                 cout << "Animal speak()" << endl;
  10.         }
  11. };
  12. class Dog :public Animal
  13. {
  14. public:
  15.         virtual void speak()
  16.         {
  17.                 cout << "Dog speak()" << endl;
  18.         }
  19. };
  20. void test()
  21. {
  22.         Animal &animal = Dog();
  23.         animal.speak();
  24.         Animal* dog = new Dog();
  25.         Animal* &an = dog;
  26.         an->speak();
  27.         delete dog;
  28. }
  29. int main()
  30. {
  31.         test();
  32.         system("pause");
  33.         return 0;
  34. }
复制代码
八.重写,重载,重定义(隐蔽)

   重载:
  

  • 同一作用域的同名函数
  
  重载(覆盖):
  

  • 有继续
  • 子类(派生类)重写父类(基类)的virtual函数
  • 函数返回值,函数名字,函数参数,必须和基类中的虚函数一致
  
  重定义(隐蔽):
  

  • 有继续
    子类(派生类)重新定义父类(基类)的同名成员(非virtual函数)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊雷无声

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表