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. SimpleInjector与MVC4集成,与Web Api集成,以及通过属性注入演示

    SimpleInjector与MVC4集成,与Web Api集成,以及通过属性注入演示   1,与MVC集成 见http://simpleinjector.codeplex.com/wikipage? ...

  2. crawler_分布式网络爬虫的设计与实现_设计图

    一.集中调度式 二.p2p 三.混合调度式 四.大型集群

  3. csdn 博客,你很努力,有人帮你-2015年03一个月17日本

    今天泛化 开始使用简书 正则表达式的博客写了两篇文章 回顾 Core Data 基本使用 总结 Xcode6新特性 简单聊聊 简书,事实上一開始学 MarkDown 语法的时候,已经用了,但是,一直认 ...

  4. ScrollView 嵌套ListView 幻灯冲突,和显示不全

    import android.content.Context; import android.util.AttributeSet; import android.widget.ListView; /* ...

  5. MAC使用小技巧(二)

    一.Safari-->广告数量不足 --原因:DNS被拦截,被恶意推送广告. ----------------------------- [ 思路 ] 修改hosts文件 $ cd /etc $ ...

  6. Java实现顺序表

    利用顺序存储结构表示的顺序表称为顺序表. 它用一组连续的地址存储单元一次存放线性表中的数据元素. 顺序表的实现是数据结构中最简单的一种. 由于代码中已经有详细注释,代码外不再阐述. 下次再陈上关于顺序 ...

  7. 用fildder 查看loveuv 刷流量时通信的数据

    loveuv是一个用来刷网页流量的站点,以下介绍怎么查看它刷流量时数据的传输 首先是注冊页面,邀请码UBMNEY 注冊账号登陆后,在账户资料页面http://www.loveuv.com/user/m ...

  8. Bootstrap-maxlength使用

    这是一个很酷jQuery实现Bootstrap小工具,输入用户同意的字符数.它可以让你显示字符用户插入的最大长度. 1.引入jquery.js及bootstrap-maxlength.js 2.给页面 ...

  9. 自动生成Makefile文件

    主要的工具有autoscan, aclocal, autoheader, autoconfig,automake 1 .创建c源文件hello.c #include <stdio.h> i ...

  10. SQL Server调优系列基础篇(常用运算符总结)

    原文:SQL Server调优系列基础篇(常用运算符总结) 前言 上一篇我们介绍了如何查看查询计划,本篇将介绍在我们查看的查询计划时的分析技巧,以及几种我们常用的运算符优化技巧,同样侧重基础知识的掌握 ...