C/C++基础知识总结——多态性
1. 多态性的概述
1.1 多态是指同样的消息被不同类型的对象接收时导致不同的行为。所谓消息是指对垒的成员函数的调用,不同行为是指不同的实现。
1.2 多态的实现
(1) 实现角度讲多态可分为两类:编译时的多态和运行时的多态。
① 编译时:编译过程中确定了同名操作的具体操作对象。静态绑定。
② 运行时:程序运行时动态确定操作针对的具体对象。动态绑定。
2. 运算符重载
2.1 运算符重载就是对已有的运算符赋予多重含义,使同一个运算符作用域不同类型的数据导致不同的行为。
2.2 运算符重载的实质是函数重载。在实现过程中,首先把制定的运算表达式转化为对运算符函数的调用,然后把运算对象转化为运算符函数的实参,然后根据实参类型确定调用的函数,这个过程是在编译过程完成的。
2.3 运算符重载的规则
(1) 只能重载C++中已经有的运算符
(2) 重载之后的优先级和结合型不变
(3) 运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。因此重载后的功能因该与原功能类似,不能改变操作对象个数,同时至少有一个操作对象是自定义类型
2.4 运算符重载的形式:重载为类的非静态成员函数和重载为类的成员函数
(1) 重载为类的成员函数
返回类型 operator 运算符(形参表)
{}
(2) 重载为非成员函数。此时有可能需要将此函数声明为友元函数。
返回类型 operator 运算符(形参表){
}
2.5 运算符重载为成员函数
(1) 双目运算符
左操作数是对象本身数据,由this指针指出,有操作数是通过重载函数的参数表实现
双目运算符B。 为了实现 oprd1 B oprd2。 应该把B实现为oprd1的重载运算符函数,该函数有一个形参,类型是oprd2对应的类型。重载后,oprd1 B oprd2即为 oprd1.operator B(oprd2)
例子:
Complex operator+ (const Complex &c2) const;
Complex Complex::operator+ (const Complex &c2) const{
reuturn ...;
}
(2) 前置单目运算符
操作数由对象的this指针指出,无需参数
比如’-‘等运算符U, U oprd.应该重载为oprd类型的成员函数,没有形参。表达式 U oprd即为 oprd.U()
例子:
Clock& operator++();
Clock& Clock::opertor++(){
reutrn ..;
}
(3) 后置单目运算符
操作数由对象的this指针指出。
比如++和--,此时,运算符应重载为对象的成员函数,这个函数有一个int 的形参,这个参数没有用处,只是为了区分前置和后置
例子:
Clock operator++(int);
Clock Clock::operator++(int)
{
return ...;
}
2.6 运算符重载为非成员函数
(1) 对于双目运算符B,如果要实现oprd1 B oprd2,其中oprd1和oprd2中只要有一个具有自定义类型,就可以将B重载为非成员函数,函数的形参oprd1 和 oprd2。经过重载后oprd1 B oprd2 就相当于函数调用operator B(oprd1, oprd2)
(2) 其他的类似,就是多个参数
(3) 例子:
class Complex{
public:
friend Complex operator+( const Complex &c1, const Complex &c2);
friend Complex ostream & operator<<( ostream &out, const Complex &c);
private:
...
}
Complex operator+(const Complex &c1, const Complex &c2){
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
ostream & operator<<(ostream &out, const Complex &c)
{
out<<c.imag;
return out;
}
3. 虚函数
3.1 虚函数是动态绑定的基础。虚函数必须是非静态的成员函数。虚函数经过派生后就可以实现运行过程中的多态。
3.2 如果需要通过基类的指针指向派生类的对象,并且访问某个与基类同名的成员,那么首先在基类中将这个同名函数声明为虚函数。
3.3 一般虚函数成员
(1) 声明语法:
virtual 函数类型 函数名(形参表)
(2) 虚函数声明只能出现在类定义中的函数原型声明中,而不能在成员函数实现的时候。
(3) 如果基类声明了虚函数,而派生类相应函数没有声明virtual,那么系统根据如下规则:
① 该函数是否与基类的虚函数有相同名称
② 该函数是否与基类的虚函数有相同的参数
③ 该函数是否与基类的虚函数有相同的返回值或者满足复制兼容规则的指针、引用型的返回值
(4) 只有虚函数是动态绑定的,如果派生类需要修改基类的行为(即重写与基类函数同名的函数),就应该在基类中将相应的函数声明为虚函数。而基类中声明 的非虚函数,通常代表那些不希望被派生类改变的功能,也是不能实现多态的。一般不要重写继承而来的非虚函数,那会导致通过基类指针和派生类指针或者对 象调用同名函数时产生不同的后果,从而引起混乱。
3.4 虚析构函数
(1) 如果基类声明为虚析构函数,则派生类的构造函数也为虚函数。
(2) 如果需要用基类的指针调用派生类的析构函数则一定要声明虚析构函数。
4. 纯虚函数与抽象类
建立抽象类就是为了通过多态使用成员函数。抽象类自身无法实例化,只能通过继承机制,生成非抽象派生类,再进行实例化。
4.1 纯虚函数
(1) 纯虚函数是一个在基类中声明的虚函数,在基类中没有定义具体的操作,要求各派生类根据实际需要给出自己的定义。
(2) 声明格式:
virtual 函数类型函数名(参数表)= 0;//后面的 = 0
(3) 声明为虚函数后,基类中就可以不再给出函数的实现部分。
(4) 如果将析构函数声明为纯虚函数,则必须在基类中给出它的实现,因为派生类的析构函数执行完后需要调用基类的析构函数。实际上,基类中是可以给出纯 虚函数的函数体,但是即使给出,也必须由派生类覆盖。
4.2 抽象类
(1) 带有纯虚函数的类是抽象类。抽象类的主要作用是通过它为一个类族建立一个公共接口。
(2) 抽象类派生出新的类后,如果派生类给出所有纯虚函数的函数实现,这个派生类就可以定义自己的对象。
(3) 抽象类不能实例化。
作者:viczzx 出处:http://www.cnblogs.com/zixuan-zhang 欢迎转载,也请保留这段声明。谢谢!
C/C++基础知识总结——多态性的更多相关文章
- java基础知识小总结【转】
java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...
- 基础知识系列☞Abstract和Virtual→及相关知识
转载地址→http://www.cnblogs.com/blsong/archive/2010/08/12/1798064.html 在C#的学习中,容易混淆virtual方法和abstract方法的 ...
- JAVA面试题集之基础知识
JAVA面试题集之基础知识 基础知识: 1.C 或Java中的异常处理机制的简单原理和应用. 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就 ...
- Java 基础知识总结
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.数据类型: 数据类型:1>.基本数据类型:1).数值型: 1}.整型类型(byte 8位 (by ...
- Java基础知识二次学习--第三章 面向对象
第三章 面向对象 时间:2017年4月24日17:51:37~2017年4月25日13:52:34 章节:03章_01节 03章_02节 视频长度:30:11 + 21:44 内容:面向对象设计思 ...
- Java基础知识回顾之七 ----- 总结篇
前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...
- Java基础知识总结(超级经典)
Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...
- C#基础知识之面向对象以及面向对象的三大特性
在C#基础知识之类和结构体中我详细记录了类.类成员.重载.重写.继承等知识总结.这里就记录一下对面向对象和面向对象三大特性的广义理解. 一.理解面向对象 类是面向对象编程的基本单元,面向对象思想其实就 ...
- 毕向东—Java基础知识总结(超级经典)
Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...
随机推荐
- 带你轻松玩转Git--瞬间创建本地仓库
在上一篇文章中我们对版本控制有了一个比较宏观的了解,同时也能够看到Git 所处在的历史地位.并且对版本控制系统的体系进行了一个宏观的对比,貌似让读者看起来挺复杂的样子. 笔者将会尽可能的简单向大家分享 ...
- C# 跨线程呼叫控制
在C# 应用程序开发, 我们经常要UI作线程分开,防止界面停止响应. 同一时候我们又须要在工作线程中更新UI界面上的控件, 以下介绍几种经常使用的方法 阅读文件夹 线程间操作无效 第一种办法:禁止编 ...
- 理解JavaScript继承
原文:理解JavaScript继承 对于JavaScript的继承和原型链,虽然之前自己看了书也听了session,但还是一直觉得云里雾里,不禁感叹JavaScript真是一门神奇的语言.这次经过Sp ...
- 证明N={1,2,...,n,...}最高万元 黄晓宁
证明N={1,2....,n....}最高万元 黄小宁(通讯:广州市华南师大南区9-303 510631) 5000年数学一直不知{2,3,....n+1,...}(n的变域是N)中"深 ...
- ZOJ 2724 Windows 消息队列 (优先队列)
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2724 Message queue is the basic fund ...
- Windows 10技术布局,谈微软王者归来
Windows 10技术布局,谈微软王者归来 每个时代都有王者,王者的成功,往往是因为恰逢其时地发布了一个成功的产品(具有里程碑意义,划时代的产品).Windows 95的成功标示着微软是PC时代的王 ...
- Swift入门教程:基本运算符
基本运算符 Swift所支持的基本运算符 赋值运算符:= 复合赋值运算符:+=.-= 算数运算符:+.-.*./ 求余运算符:% 自增.自减运算符:++.-- 比较运算符:==.!=.>.< ...
- Coreseek:索引和检测的第二步骤施工
1,非常索引easy,代码行 g:/service/coreseek/bin/indexer -c g:/service/coreseek/etc/csft_mysql.conf person 在 ...
- 使用IntelliLock加密授权你的.Net程序
原文:使用IntelliLock加密授权你的.Net程序 转自:http://www.nsoff.com/post/2012/05/23/%E4%BD%BF%E7%94%A8IntelliLock%E ...
- 谢绝艳照门 - 手把手教你把当今很hit的家庭监控IP Camera变得网络安全起来
IP Camerars现在已经越来越便宜了,很多人都可以买得起,并且大家也乐意去购买,因为它们的确是用来监控你在高房价的中国购买的爱巢的非常便利的设备.当然,配套的监控应用也层出不穷,从通用的家庭安全 ...