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++基础知识总结——多态性的更多相关文章

  1. java基础知识小总结【转】

    java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...

  2. 基础知识系列☞Abstract和Virtual→及相关知识

    转载地址→http://www.cnblogs.com/blsong/archive/2010/08/12/1798064.html 在C#的学习中,容易混淆virtual方法和abstract方法的 ...

  3. JAVA面试题集之基础知识

                           JAVA面试题集之基础知识 基础知识:  1.C 或Java中的异常处理机制的简单原理和应用. 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就 ...

  4. Java 基础知识总结

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.数据类型:  数据类型:1>.基本数据类型:1).数值型: 1}.整型类型(byte  8位   (by ...

  5. Java基础知识二次学习--第三章 面向对象

    第三章 面向对象   时间:2017年4月24日17:51:37~2017年4月25日13:52:34 章节:03章_01节 03章_02节 视频长度:30:11 + 21:44 内容:面向对象设计思 ...

  6. Java基础知识回顾之七 ----- 总结篇

    前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...

  7. Java基础知识总结(超级经典)

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

  8. C#基础知识之面向对象以及面向对象的三大特性

    在C#基础知识之类和结构体中我详细记录了类.类成员.重载.重写.继承等知识总结.这里就记录一下对面向对象和面向对象三大特性的广义理解. 一.理解面向对象 类是面向对象编程的基本单元,面向对象思想其实就 ...

  9. 毕向东—Java基础知识总结(超级经典)

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

随机推荐

  1. RQNOJ PID4 / 数列(位运算)

    题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是: 1,3,4,9,10,12,13,… (该序列实际上就是 ...

  2. OJ提交题目中的语言选项里G++与C++的区别(转载)

    原文链接:http://blog.polossk.com/201405/c-plus-plus-g-plus-plus G++? 首先更正一个概念,C++是一门计算机编程语言,G++不是语言,是一款编 ...

  3. shell编程控制结构:expr、let、for、while、until、shift、if、case、break、continue、功能、select

    1.expr计算整数变量值 s=`expr 2 + 3` 运算符号和參数之间要有空格分开: 2.let命令 let s=(2+3)*4 echo $s 3.for语句 for 变量 in 列表 do ...

  4. 6最好的之一 HTML5/CSS3 演示(PPT)框架

    HTML 是全世界最流行的网页编程语言.而HTML5是这门语言的升级版本号.越来越多的开发人员和设计师開始使用HTML5.以下介绍几个 HTML5/CSS3 的演示工具和框架,你能够用它们来创建你的网 ...

  5. [Asp.net]站点地图SiteMap

    原文:[Asp.net]站点地图SiteMap 引言 在项目中发现使用站点地图的控件,之前没总结过这方面的东西,就写了一个demo测试了一下,这里记录一下,算是总结吧. Web.sitemap < ...

  6. 用了TextMate才知道什么叫神级Editor

    用了TextMate才知道什么叫神级Editor 一直用Eclipse作为开发Ruby和Java项目的IDE,但是太耗内存,再开个Firefox和虚拟机就可以直接将MBP弄残了..看到大家都对Mac下 ...

  7. Mediator - 中介者模式

    定义 用一个中介对象来封装一系列的对象的交互.中介者使各对象不须要显示地相互使用,从而使其耦合松散,并且能够独立的改变他们之间的交互. 案例 比方有一个图像界面,在界面上有一个输入框LineEdit, ...

  8. JVM截至多少线程可以创建: unable to create new native thread

    最近的测试需要很长的连接server.这些数据需要达到100W长连接,试client.一个线程来保持连接.查找linuxserver创建者默认3200当多个线程.这个错误将得到"java.l ...

  9. leetcode[61] Unique Paths

    题目:给定一个m*n的矩阵,从头开始,只能往右边和下边走,一次走一格,知道走到最后一个(右下角)为止.总共有多少种走法. 典型的动态规划吧.其实从头走到尾部,和从尾部开始走到头是一样的次数.我们用一个 ...

  10. Vs2010中水晶报表引用及打包

    原文:Vs2010中水晶报表引用及打包 转自:http://yunhaifeiwu.iteye.com/blog/1172283 Vs2010中水晶报表引用 在sap官网中下载支持vs 2010中的水 ...