博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++中的多态
阅读量:4210 次
发布时间:2019-05-26

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

多态指的是同一个行为,有不同的表现形式,在c++中,要实现多态的函数,必须在其函数前面加上virtual函数,否则,起不到多态作用。

不加virtual关键字的后果:

#include 
using namespace std;class Parent{public: Parent(int a) { this->a = a; cout << "Parent a" << a << endl; } void print() //子类的和父类的函数名字一样 { cout << "Parent 打印 a:" << a << endl; }protected:private: int a;};class Child : public Parent{public: Child(int b) : Parent(10) //父类的构造函数中有参数,因此在子类的构造函数中,要进行参数初始化列表 { this->b = b; cout << "Child b" << b << endl; } void print() { cout << "Child 打印 b:" << b << endl; }protected:private: int b;};void main(){ Parent* base = NULL; Parent p1(20); Child c1(30); base = &p1; base->print(); //执行父类的打印函数 base = &c1; base->print(); //在这里执行的也是父类的打印函数,因为重写的那个函数都没有加virtual关键字 cout << "hello..." << endl; system("pause"); return;}/**输出:Parent a20Parent a10Child b30Parent 打印 a:20Parent 打印 a:10*/

分析:在上面的代码中,重写的函数print没有加上virtual关键字,然后在main中用parent指针接收的时候,哪怕让它指向一个子类的类型,调用的结果也是父类的print函数,这是因为,这在c++中是静态联编的(没有加virtual关建字的时候),根据指针的类型从而就决定其指向什么类型。(C/C++是静态编译型语言,在编译时,编译器自动根据指针的类型判断指向的是一个什么样的对象,在编译此函数的时,编译器不可能知道指针 p 究竟指向了什么。编译器没有理由报错。于是,编译器认为最安全的做法是编译到父类的print函数,因为父类和子类肯定都有相同的print函数。)

 

但是在加了virtual关键字之后,多态的作用就体现出来,具体代码如下,注意看代码注释:

#include 
using namespace std;class Parent{public: Parent(int a) { this->a = a; cout << "Parent a" << a << endl; } virtual void print() //子类的和父类的函数名字一样 { cout << "Parent 打印 a:" << a << endl; }protected:private: int a;};class Child : public Parent{public: Child(int b) : Parent(10) //父类的构造函数中有参数,因此在子类的构造函数中,要进行参数初始化列表 { this->b = b; cout << "Child b" << b << endl; } virtual void print() { cout << "Child 打印 b:" << b << endl; }protected:private: int b;};void main(){ Parent* base = NULL; Parent p1(20); Child c1(30); base = &p1; base->print(); //执行父类的打印函数 base = &c1; base->print(); //执行子类的print函数,多态的作用就会体现出来 cout << "hello..." << endl; system("pause"); return;}/**输出:Parent a20Parent a10Child b30Parent 打印 a:20Child 打印 b:30*/

再看另外一个多态的例子:

#include 
using namespace std;//HeroFighter AdvHeroFighter EnemyFighterclass HeroFighter{public: virtual int power() //C++会对这个函数特殊处理 { return 10; }};class EnemyFighter{public: int attack() { return 15; }};class AdvHeroFighter : public HeroFighter{public: virtual int power() { return 20; }};class AdvAdvHeroFighter : public HeroFighter{public: virtual int power() { return 30; }};//多态威力//1 PlayObj给对象搭建舞台 看成一个框架//15:20void PlayObj(HeroFighter *hf, EnemyFighter *ef){ //不写virtual关键字 是静态联编 C++编译器根据HeroFighter类型,去执行 这个类型的power函数 在编译器编译阶段就已经决定了函数的调用 //动态联编: 迟绑定: //在运行的时候,根据具体对象(具体的类型),执行不同对象的函数 ,表现成多态. if (hf->power() > ef->attack()) //hf->power()函数调用会有多态发生 { printf("主角win\n"); } else { printf("主角挂掉\n"); }}//多态的思想//面向对象3大概念//封装: 突破c函数的概念....用类做函数参数的时候,可以使用对象的属性 和对象的方法 //继承: A B 代码复用//多态 : 可以使用未来...//多态很重要//实现多态的三个条件//C语言 间接赋值 是指针存在的最大意义//是c语言的特有的现象 (1 定义两个变量 2 建立关联 3 *p在被调用函数中去间接的修改实参的值)//实现多态的三个条件//1 要有继承 //2 要有虚函数重写//3 用父类指针(父类引用)指向子类对象....void main(){ HeroFighter hf; AdvHeroFighter Advhf; EnemyFighter ef; AdvAdvHeroFighter advadvhf; PlayObj(&hf, &ef); PlayObj(&Advhf, &ef); PlayObj(&advadvhf, &ef) ; //这个框架 能把我们后来人写的代码,给调用起来 cout<<"hello..."<
ef.attack()) { printf("主角win\n"); } else { printf("主角挂掉\n"); } if (Advhf.power() > ef.attack()) { printf("Adv 主角win\n"); } else { printf("Adv 主角挂掉\n"); } cout<<"hello..."<

总结:

多态可以面向未来(只要接口跟以前相同,多态封装成框架之后,可以调用未来的代码),实现多态的3个要求:

(1) 要有继承

(2) 要有虚函数重载

 (3) 要有父类的指针或者引入指向子类对象

转载地址:http://srzmi.baihongyu.com/

你可能感兴趣的文章
PowerDesigner 系列 小结
查看>>
Oracle 升级10.2.0.5.4 OPatch 报错Patch 12419392 Optional component(s) missing 解决方法
查看>>
Oracle sessions,processes 和 transactions 参数 关系 说明
查看>>
RMAN 备份报错 RMAN-06207 RMAN-06208 解决方法
查看>>
[INS-35172] Target database memory (XXMB) exceeds the systems available shared memory ({0}MB) 解决方法
查看>>
深入理解 OUI(Oracle Universal Installer)
查看>>
Oracle LOB 详解
查看>>
磁盘性能 -- IOPS 和 吞吐量 说明
查看>>
Oracle Heap size XXK exceeds notification threshold (2048K) 解决方法
查看>>
Oracle Gloden Gate 系列三 -- GG 支持与不支持的对象类型与操作 说明
查看>>
PowerDesigner PDM 生成SQL脚本 去除 引号 方法
查看>>
Oracle Golden Gate 系列四 -- GG 安装 与 卸载 理论知识
查看>>
关系数据库 范式(NF: Normal Form) 说明
查看>>
Oracle Golden Gate 系列五 -- GG 使用配置 说明
查看>>
Oracle Golden Gate 系列六 -- 11gR2 Ora2Ora 单向复制 GG 示例
查看>>
Oracle Golden Gate 系列七 -- 配置 GG Manager process
查看>>
ORA-00600:[32695], [hash aggregation can't be done] 解决方法
查看>>
Oracle SQL中使用正则表达式 执行报ORA-07445 [_intel_fast_memcpy.A()+10] 错误
查看>>
Oracle TABLE ACCESS BY INDEX ROWID 说明
查看>>
ORA-00600 [kmgs_parameter_update_timeout_1], [27072] ORA-27072 解决方法
查看>>