C++多态小结
C++ 多态
多态
多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。
C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。
下面的实例中,基类 Shape 被派生为两个类,如下所示:
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0){
width = a;
height = b;
}
int area(){
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) {}
int area (){
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) {}
int area (){
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
int a = rec.area();
cout<<a<<endl;
int b = tri.area();
cout<<b<<endl;
return 0;
}
以上代码,就是Shape被派生为Rectangle 和 Triangle 两个类,正显示了C++的多态性。
其运行输出结果为:
Rectangle class area :
70
Triangle class area :
25
虚函数
虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
纯虚函数
您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
我们可以把基类中的虚函数 area() 改写如下:
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;
};
= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数。
注意
- 派生类中一般需要重定义所继承的虚函数,若没有则使用基类版本
- 一旦函数被声明为虚函数,则派生中一直为虚函数;派生类中可以使用关键字virtual,也可以不保留
- 虚函数重定义时候,原型不能变:返回类型、形参数目和类型都不能更改;若不一致则为重载
- 构造(三大类)函数不能做为虚函数,静态成员函数不能定义为虚函数
在构造函数运行的时候,这个对象的动态类型还不完整,没有办法确定它到底是什么类型,故构造函数不能动态绑定
静态的数据成员被所有的对象共享,静态数据成员不属于对象,而是属于类的;静态成员函数也是属于类的,它没有this指针,它无法进行对象的判别 - 构造及析构函数体内切勿使用虚函数
在进行基类成员构造的时候对象就被编译器视为基类类型;派生类部分的成员还没有初始化,想调用派生类的虚函数相当于要去使用未定义的数据;另外,若此时涉及到调用虚函数,也是基类的虚函数,是不可能正确实现多态的
析构函数同理 - 虚析构函数
虚析构函数是根据对象的类型来动态释放基类/派生类的对象的
意味着可以用基类的引用释放派生类的对象的空间
当基类中有虚函数时,最好将析构函数也声明为虚函数 - 虚函数的屏蔽
作用域符号 : : 可以强制调用指定的虚函数,因为派生类的对象可以赋值给基类,传入派生类对象依然可以执行基类定义的虚函数 - 纯虚函数 纯虚函数是用来被继承的;纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务
C++多态小结的更多相关文章
- Java中的继承和多态
1. 什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法,使得子类具有父类相同的行为. 特点:在继承关系中,父类更通用.子类更具体.父类具有更 ...
- 【Java学习笔记之十六】浅谈Java中的继承与多态
1. 什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法,使得子类具有父类相同的行为. 特点:在继承关系中,父类更通用.子类更具体.父类具有更 ...
- 面向对象【day07】:多态(九)
本节内容 概述 多态 小结 一.概述 多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作 ...
- java中继承和多态
转自原文http://blog.csdn.net/xinxin19881112/article/details/2944760 若冒犯博主,请勿见怪! 1. 什么是继承,继承的特点? 子类继承父类的 ...
- java学习第一阶段——面向对象
你聪明有人会说你心机重, 你靠的是努力有人会说你运气好, 你说自己天生乐观有人会说你虚假, 有时候, 你明明就是一杯白水, 却被人硬生生逼成了满肚子憋屈的碳酸饮料. 人一生要遇见太多人, 即使有些话字 ...
- Java——面向对象的特征三:多态性
2.5面向对象的特征三:多态性 2.5.1 关于java语言中的向上转型和向下转型 ①向上转型(upcasting) : 子--->父(自动类型转换) ②向下转型(downcasting) : ...
- 12.instanceof和类型转换
Instanceof: 判断一个对象是什么类型的~,可以判断两个类之间是否存在父子关系 package com.oop.demo07; public class Person { public voi ...
- 程序设计基础·Java学习笔记·面向对象(下)
Java程序设计基础之面向对象(下) (补充了上的一些遗漏的知识,同时加入了自己的笔记的ヾ(•ω•`)o) (至于为什么分P,啊大概是为了自己查笔记方便(?)应该是("` 3′") ...
- .NET项目开发—浅谈面向对象的纵横向关系、多态入口,单元测试(项目小结)
阅读目录: 1.开篇介绍 2.使用委托消除函数串联调用 2.1.使用委托工厂转换两个独立层面的对象 3.多态入口(面向对象继承体系是可被扩展的) 4.多态的受保护方法的单元测试(Protected成员 ...
随机推荐
- HDU 3923 Invoker | 暑训Day1 C题填坑
暑训第一天,专题为组合数学与概率期望. 最近一个月都没有学习新的知识,上午听聚聚讲课头脑都是一片空白.加上长期没刷题,下午做练习题毫无感觉.到晚上总算理清了蓝书上的一些概念,跟着榜单做题.最后唯独剩下 ...
- <每日一题>题目24:冒泡排序
''' 冒泡排序:比较相邻元素,顺序错误就交换顺序 ''' import random import cProfile def bubble_Sort(nums): for i in range(le ...
- SDOI2019 R2退役记
还是退役了呀 Day -1 早上loli发了套题结果啥都不会 之后胡爷爷就秒了道数据结构 不过也没什么人做,于是全机房都在愉快的划水 下午来机房打了场luogu的\(rated\)赛,还是啥都不会 之 ...
- Access数据库连接字符串
<connectionStrings> <add name="connStr" connectionString="server=.;uid=home; ...
- 《数据结构与算法分析——C语言描述》ADT实现(NO.05) : 散列(Hash)
散列(Hash)是一种以常数复杂度实现查找功能的数据结构.它将一个关键词Key,通过某种映射(哈希函数)转化成索引值直接定位到相应位置. 实现散列有两个关键,一是哈希函数的选择,二是冲突的处理. 对于 ...
- intellij idea中去除@Autowired注入对象带来的下划线提示
场景: idea中通过@Autowired注入的对象一直有下划线提示,虽然不影响运行 解决:改变@Autowired的检查级别即可. 快捷键:Ctrl+Alt+s,进入idea设置界面,输入inspe ...
- Ad Infinitum 8 - Math Programming Contest
比赛链接 A题 如果当前数是1,那么后面无论是几都会加1或者当后面数是1的时候加2,所以记录一下后面的数中1的个数(加2)即可. 如果当前数是2,那么只有当后面的数为1或者为2时才可以加1,所以再记录 ...
- Navicat12激活,最新版本v12.1.18,原版激活[windows]
1.navicat_premium原版安装包 :官网下载地址2.注册工具 :github地址 本次用到的软件我已经打包好 : 蓝奏云 我安装navicat的路径在:I:\Navicat P ...
- HDFS常用Java API
- Leetcode150. Evaluate Reverse Polish Notation逆波兰表达式求值
根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说 ...