C++中多态的概念和意义
1,函数重写回顾:
1,父类中被重写的函数依然会继承给子类;
2,子类中重写的函数将覆盖父类中的函数;
1,重写父类当中提供的函数是因为父类当中提供的这个函数版本不能满足我们的需求,因此我们要重写;
2,期望只要是子类对象,则调用子类当中的版本,而不是父类当中定义的函数版本;
3,通过作用域分辨符(::)可以访问到父类中的函数;
1,代码示例:
Child c;
Parent* p = &c; c.Parent::print(); // 从父类中继承;I'm Parent.
c.print(); // 在子类中重写;I'm Child. p->print(); // 父类中定义;I'm Parent.不是我们期望的版本,因为 p 指向了子类对象,期望调用子类版本
2,面相对象中期望的行为:
1,根据实际的对象类型判断如何调用重写函数;
1,而不是根据指针类型(编译器默认的安全行为);
2,父类指针(引用)指向:
1,父类对象,则调用父类中定义的函数;
2,子类对象,则调用子类中定义的重写函数;
3,面向对象中的多态的概念:
1,根据实际的对象类型决定函数调用的具体目标;
1,相同的行为方式可能导致不同的行为结果,即产生了多种形态行为,即多态;
2,同样的调用语句在实际运行时有多种不同的表现形态;
1,同一行语句展现了多种不同的表现形态,多态本质;
4,C++ 语言直接支持多态的概念:
1,通过使用 virtual 关键字对多态进行支持;
1,什么时候用 virtual ?
2,定义类的时候,觉得某一个函数在后续被继承的过程当中,有可能被重写,就是用 virtual 关键字修饰这个函数;
2,被 virtual 声明的函数被重写后具有多态特性;
1,函数名和参数都必须一样,若函数名相同但参数不同,这是同名覆盖;
3,被 virtual 声明的函数叫做虚函数(因为 virtual 的意思就是虚拟的);
1,虚函数被继承后依然是虚函数,不用再被 virtual 修饰;
5,多态的初体验编程实验:
#include <iostream>
#include <string> using namespace std; class Parent
{
public:
virtual void print() // 这个函数可能被继承的子类重写,所以加上virtual 关键字来修饰它,称为虚函数,实现多态;
{
cout << "I'm Parent." << endl;
}
}; class Child : public Parent
{
public:
void print() // 虽然没有写 virtual 关键字,但是由于继承的关系,它就是虚函数;一般工程中没必要在子类中写 virtual;
{
cout << "I'm Child." << endl;
}
}; void how_to_print(Parent* p)
{
p->print(); // 希望展现多态行为;
} int main()
{
Parent p;
Child c; how_to_print(&p); // 期望打印: I'm Parent. 实际打印:I'm Parent.
how_to_print(&c); // 期望打印: I'm Child. 实际打印:I'm Child. return ;
}
6,多态意义:
1,在程序运行过程中展现出动态的特性;
1,编译时无法决定究竟调用哪一个版本的实现;
2,函数重写必须多态实现,否则没有意义;
1, C++ 后续语言(Java、C#)中,只要是重写,一定是虚函数,不需要显示声明 virtual 关键字;
3,多态是面向对象组件化程序设计的基础特性;
1,后续学习中多态特性会被变着花样玩儿,特别是设计模式中绝大多数模式都和多态相关;
7,理论中的概念:
1,静态联编:
1,在程序的编译期间就能确定具体的函数调用;
1,如函数重载;
2,动态联编(多态):
1,在程序实际运行后才能确定具体的函数调用;
1,如函数重写;
8,动态联编与静态联编实例分析:
#include <iostream>
#include <string> using namespace std; class Parent
{
public:
virtual void func()
{
cout << "void func()" << endl;
} virtual void func(int i)
{
cout << "void func(int i) : " << i << endl;
} virtual void func(int i, int j)
{
cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;
}
}; class Child : public Parent
{
public:
void func(int i, int j)
{
cout << "void func(int i, int j) : " << i + j << endl;
} void func(int i, int j, int k) // 子类同名覆盖父类当中的函数,重载同一作用域当中的函数;
{
cout << "void func(int i, int j, int k) : " << i + j + k << endl;
}
}; void run(Parent* p)
{
p->func(, ); // 展现多态的特性,动态联编
} int main()
{
Parent p; p.func(); // 静态联编
p.func(); // 静态联编
p.func(, ); // 静态联编 cout << endl; Child c; c.func(, ); // 静态联编 cout << endl; run(&p);
run(&c); return ;
}
9,多态编程实验:
#include <iostream>
#include <string> using namespace std; class Boss
{
public:
int fight()
{
int ret = ; cout << "Boss::fight() : " << ret << endl; return ret;
}
}; class Master
{
public:
virtual int eightSwordKill()
{
int ret = ; cout << "Master::eightSwordKill() : " << ret << endl; return ret;
}
}; class NewMaster : public Master
{
public:
int eightSwordKill() // 重写八剑齐飞
{
int ret = Master::eightSwordKill() * ; cout << "NewMaster::eightSwordKill() : " << ret << endl; return ret;
}
}; void field_pk(Master* master, Boss* boss)
{
int k = master->eightSwordKill(); // 赋值兼容性加上函数重载,根据实际的对象调用函数;
int b = boss->fight(); if( k < b )
{
cout << "Master is killed..." << endl;
}
else
{
cout << "Boss is killed..." << endl;
}
} int main()
{
Master master;
Boss boss; cout << "Master vs Boss" << endl; field_pk(&master, &boss); cout << "NewMaster vs Boss" << endl; NewMaster newMaster; field_pk(&newMaster, &boss); return ;
}
10,小结:
1,函数重写只可能发生在父类与子类之间;
2,根据实际对象的类型确定调用的具体函数;
3,virtual 关键字是 C++ 中支持多态的唯一方式;
4,被重写的虚函数课表现出多态的特性;
5,虚函数和多态的关系:
1,多态是面向对象理论当中的一个概念,它和具体的程序设计语言是没有关系的,也就是说多态指的仅仅是相同的行为方式,不同的行为结果;
2,这种多态的表现形式在 C++ 中由虚函数来实现;
C++中多态的概念和意义的更多相关文章
- java中多态的概念
概念: 简答来说,多态(Polymorphism)是具有表现多种形态的能力的特征. 更专业的说法是:同一个实现接口,使用不同的实例而执行不同的操作. 好处: 通过多态可以减少类中代码量,可以提高 ...
- 深入Java核心 Java中多态的实现机制(1)
在疯狂java中,多态是这样解释的: 多态:相同类型的变量,调用同一个方法时,呈现出多中不同的行为特征, 这就是多态. 加上下面的解释:(多态四小类:强制的,重载的,参数的和包含的) 同时, 还用人这 ...
- 个人对Java中多态的一些简单理解
什么是多态 面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 多态的定义:指允许不同类的对象对同一消息做出响应.即同一 ...
- Java中多态的一些简单理解
什么是多态 .面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. .多态的定义:指允许不同类的对象对同一消息做出响应.即 ...
- 『Python题库 - 简答题』 Python中的基本概念 (121道)
## 『Python题库 - 简答题』 Python中的基本概念 1. Python和Java.PHP.C.C#.C++等其他语言的对比? 2. 简述解释型和编译型编程语言? 3. 代码中要修改不可变 ...
- Javase中多态polymorphic的简单介绍
-------------多态----------------- (1)面向对象三大核心思想: 1.封装 2.继承 3.多态 (2)多态定义:父类的引用指向子类的对象. (3)引用指的是父 ...
- Mycat中的核心概念
Mycat中的核心概念 Mycat中的核心概念 1.数据库中间件 Mycat 是一个开源的分布式数据库系统,但是由于真正的数据库需要存储引擎,而 Mycat 并没有 存储引擎,所以并 ...
- 从虚拟机指令执行的角度分析JAVA中多态的实现原理
从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...
- java中多态的实现机制
多态的概念: 简单来说就是事物在运行过程中存在的不同状态,即父类或接口定义的引用变量指向子类或具体实现类的实例对象.程序调用方法在运行期才进行动态绑定,而不是引用变量的类型中定义的方法. 多态存在的前 ...
随机推荐
- C# AVI Image 转换
AVI视频库 http://download.csdn.net/download/qc_id_01/9970151 Avi视频文件的编码有很多,这个库只支持部分Avi文件,有些Avi文件不支持,具体哪 ...
- Angular 文档中的修改链接是从哪里改的
如何修改修改的文本的链接. 如下图表示的,如何修改这个地方的链接到自己的 SCM 中. 你需要修改的文件为: aio\tools\transforms\templates\lib\githubLink ...
- Lucas定理初探
1.1 问题引入 已知\(p\)是一质数,求\(\dbinom{n}{m}\pmod{p}\). 关于组合数,它和排列数都是组合数学中的重要概念.这里会张贴有关这两个数的部分内容. 由于Lucas定理 ...
- 【BZOJ4552】排序(线段树,二分)
题意:给定一个n个数的排列,有m次操作:op,l,r op=0时表示将位置[L,R]升序排序 op=1时表示将位置[L,R]降序排序 最后询问第q个位置上的数字 n,m,q<=1e5 思路:Fr ...
- 16.Python input()函数:获取用户输入的字符串
input() 函数用于向用户生成一条提示,然后获取用户输入的内容.由于 input() 函数总会将用户输入的内容放入字符串中,因此用户可以输入任何内容,input() 函数总是返回一个字符串. 例如 ...
- Oracle用函数或PIVOT实现行转列
原数据: 目标数据: 实现代码: SELECT YEAR AS "年", SUM (DECODE (QUATER, 1, RATE, 0)) AS "季度一", ...
- C++入门经典-例3.19-使用break跳出循环
1:代码如下: // 3.19.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...
- Mysql和Orcale的区别
有很多应用项目, 刚起步的时候用MYSQL数据库基本上能实现各种功能需求,随着应用用户的增多,数据量的增加,MYSQL渐渐地出现不堪重负的情况:连接很慢甚至宕机,于是就有把数据从MYSQL迁到ORAC ...
- IDEA 创建maven jar、war、 pom项目
创建java jar.pom项目时创建maven-archetype-quickstart 创建java war项目时创建maven-archetype-webapp
- es6 的数组的方法
es6 数组的拓展 数组的类 Array 数组的定义: 1. var arr=[]; 2. var arr=new Array(3) // 3 代表有三个元素 arr[0]=12; arr[1]=24 ...