博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第十六章 多态性
阅读量:5789 次
发布时间:2019-06-18

本文共 4182 字,大约阅读时间需要 13 分钟。

1.  相同函数名具有多态性:

  重载 覆盖  隐藏
共同点:  函数名相同 函数名相同 函数名相同
不同点: 

同类、参数类型、数量不同 

或 有无const 

不同类,同参,有基virtual 

不同类,同参,且无virtual

不同类,不同参(不论有无virtual) 

体现: 由函数调用(静态联编) 由函数调用取决于object(动态联编) 取决于pointer(不能体现多态性)

①  译时的多态(由函数名来调用时体现):重载:同类,不同参

②  运行时的多态(用指向不同类的指针来调用):

覆盖:  不同类,同参,基类有virtual(由指针指向的类型来决定,体现了多态性)

隐藏:①不同类,同参,基类无virtual②不同类,不同参(不论有无virtual)(由指针来决定,不能体现多态性)

1.  为什么要使用多重继承

多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数。C++多态性是通过虚函数(virtual)来实现的。

2.  在派生类中增加函数

RTTI:  ①typeid返回指针或引用所指的实际类型

②dynamic_cast 将基类类型的指针或引用安全的转换成派生类类型的指针或引用

dynamic_cast<son*>pf->beautiful();

注意:①硬性转换尽量少用②必须使用虚函数

3.  使用多重继承

使用多重继承可以避免:①在基类放接口函数②用RTTI将父类的指针转换成派生类的

调用多态性,必须要用虚析构函数

4.  模拟抽象类

抽象类的作用:

为了实现一个统一的指针,我们可以定义一个类,再由这个类派生出父类和母类

5.  纯虚函数与抽象类

☆抽象类起到接口的作用,便于父类指针调用子类的对象

virtual viod A()=0;包含一个或者多个纯虚函数的类叫抽象类;

☆纯虚函数只起到接口的作用,要且必须在子类中重新定义

纯虚基类只能申明抽象类的指针,不能开辟抽象类的空间

6.  抽象类实例

7.  复杂的抽象结构

8.  慎用多重继承

在用单一继承可以实现的情况下不要使用多重继承

1 #include 
2 using namespace std; 3 class animal 4 { 5 public: 6 animal(int); 7 virtual ~animal(){cout<<"析构动物..\n";} 8 virtual int getage() {
return itsage;} 9 virtual void sleep()=0; //声明6个纯虚函数 10 virtual void eat()=0; 11 virtual void propagate()=0; 12 virtual void move()=0; 13 virtual void body()=0; 14 virtual void show()=0; 15 private: 16 int itsage; 17 }; 18 animal::animal(int age):itsage(age) 19 { 20 cout<<"创建动物...\n"; 21 } 22 class Mammalia:public animal //派生了另一个抽象类哺乳动物类 23 { 24 public: 25 Mammalia(int age):animal(age){cout<<"创建哺乳类...\n";} //子类在构造自己的同时也要构造基类部分 26 virtual ~Mammalia(){cout<<"析构哺乳类...\n";} 27 virtual void propagate(){cout<<"哺乳类是胎生动物,通过胚胎来繁殖后代。\n";} 28 //该类仅仅覆盖了基类的繁殖方法propagate() 29 }; 30 class bird:public animal //鸟类将动物类的6个纯虚函数全部覆盖,因此该类不是抽象类 31 { 32 public: 33 //子类在构造自己的同时也要构造基类部分 34 bird(int age):animal(age){cout<<"创建鸟类...\n";} 35 virtual ~bird(){cout<<"析构鸟类...\n";} 36 virtual void sleep(){cout<<"鸟类喜欢站着睡觉。\n";} 37 virtual void eat(){cout<<"极个别鸟类吃肉,其他都是吃素。\n";} 38 virtual void propagate(){cout<<"鸟类是卵生动物,通过排卵来繁殖后代.";} 39 virtual void move(){cout<<"鸟类可以飞...\n";} 40 virtual void body(){cout<<"鸟类体表被覆羽毛,前肢变为翼!";} 41 virtual void show(){cout<<"鸟类的一般寿命为:"<
<
>choice; 80 switch(choice) 81 { 82 case 1:ph=new pig(1); //选择1,创建猪类对象,并初始化猪类的私有变量itsage的值 83 break; 84 case 2:ph=new human(80); //选择2,创建人类对象,并初始化人类的私有变量itsage的值 85 break; 86 case 3:ph=new bird(50); //选择3,创建鸟类对象,并初始化鸟类的私有变量itsage的值 87 break; //由于哺乳动物是个抽象类,不能实例化对象,因此没有设置该类的选项 88 default:quit=true; //假如选择了其他,那么默认将quit的值赋为true 89 break; 90 } 91 if(quit) //假如quit的值为真 92 break; //退出while循环 93 ph->show(); //用ph指针访问虚函数show,要注意,这里的show()不再是纯虚函数 94 ph->eat(); //用ph指针访问虚函数eat 95 ph->propagate(); //用ph指针访问虚函数propagate 96 ph->move(); //用ph指针访问虚函数move 97 ph->sleep(); //用ph指针访问虚函数sleep 98 ph->body(); //用ph指针访问虚函数body 99 cout<<"\n";100 }101 return 0;102 }

 

本章总结:

/** ************重载,重写(覆盖),隐藏的识别*************重载:如何调用取决于参数覆盖:如何调用取决于object(有virtual 同名 同参)隐藏:如何调用取决于pointera、编译时多态性:通过重载函数实现 b、运行时多态性:通过虚函数实现。包含纯虚函数(virtual void funtion()=0 )的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。小结:1、有virtual才可能发生多态现象2、不发生多态(无virtual)调用就按原类型调用*/#include
using namespace std;class Base{public: virtual void f(float x) { cout<<"Base::f(float)"<< x <
f(3.14f); // Derived::f(float) 3.14 pd->f(3.14f); // Derived::f(float) 3.14 // Bad : behavior depends on type of the pointer pb->g(3.14f); // Base::g(float) 3.14 pd->g(3.14f); // Derived::g(int) 3 // Bad : behavior depends on type of the pointer pb->h(3.14f); // Base::h(float) 3.14 pd->h(3.14f); // Derived::h(float) 3.14 return 0;}

 

转载于:https://www.cnblogs.com/zenseven/p/3794213.html

你可能感兴趣的文章
spring之jdbcTemplate的增删改查操作--不使用配置文件
查看>>
iOS8中添加的extensions总结(一)——今日扩展
查看>>
luogu P1462 通往奥格瑞玛的道路
查看>>
IOS中的多线程之GCD
查看>>
oracle快速创建可用用户
查看>>
添加捕获异常
查看>>
POJ 1745 Divisibility【DP】
查看>>
KVM虚拟机管理
查看>>
BloomFilter ——大规模数据处理利器
查看>>
数位DP按位枚举模板
查看>>
配置LANMP环境(9)-- 安装Git与vsftp
查看>>
Java 中的PO VO DTO BO
查看>>
html5 移动端单页面布局
查看>>
JavaScript概述
查看>>
bzoj2039[2009国家集训队]employ人员雇佣
查看>>
第6天
查看>>
九眼合同智能审核系统运用NLPIR大数据技术进行核查
查看>>
回溯枚举法
查看>>
.Net中的RealProxy实现AOP
查看>>
浮动元素居中
查看>>