一、基本概念

对于C++中经常出现的函数名称相同但是参数列表或者返回值不同的函数,主要存在三种情况:


1.函数重写(override)

函数重载主要实现了父类与子类之间的多态性,子类中定义与父类中名称和参数以及返回值都相同的虚函数。

1)重写的函数不能是static函数,必须是virtual函数,即函数在原始的基类中被声明为虚函数;

2)重写函数与基类函数分在两个类的声明和定义中,这也就导致二者的作用域不同;

3)重写函数的名称、参数列表以及返回值(即函数原型)都要与基类的函数相同;

4)重写函数的访问修饰符可以不同,尽管virtual函数是private的,在派生类中重写的函数可以是public或protect的

2.函数重载(overload)

指函数名称相同但是参数类型或者参数顺序不同的相同作用域中的函数,函数重载不能靠返回值来进行区分;

3.重定义(redefine)

指子类重新定义父类中的非虚函数(参数列表可以不同),这样父类中的对应函数将被隐藏。


二、重写(override)与重载(overload)的区别

1、函数重写是子类和父类之间的继承关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系;

2、重写需要子类和父类中的两个函数的函数原型完全相同;重载要求两个函数参数列表不同;

3、在重写关系中,调用具体调用哪一个函数是根据(对象对应存储空间的实际类型)为准的,这涉及到动态绑定和静态绑定的问题,也就是虚函数的调用机制,而函数重载主要是靠形参列表的不同来区分具体调用哪个函数的。

#include <iostream>
using namespace std; class BasicClass{
private:
int a;
public:
//构造函数重载
BasicClass(){ a=; };
BasicClass(int i):a(i){ };
BasicClass(const BasicClass &b):a(b.a){};
//基类的析构函数需要声明为虚函数
virtual ~BasicClass(){}; //函数重载实例
void overloadFunc(int k){
cout<<"overloadFunc single parameter:"<<k<<endl;
}; void overloadFunc(int k,int t){
cout<<"overloadFunc two parameters:"<<endl;
cout<<"k:"<<k<<endl;
cout<<"t:"<<t<<endl;
}; virtual void overrideFunc(){
cout<<"overrideFunc From Basic class!"<<endl;
}
}; class DeriveClass : public BasicClass{
private:
public:
//子类构造函数需要考虑到具体的基类成员初始化
//但是初始化的具体实现要交给相应类的构造函数来实现
DeriveClass(){};
DeriveClass(int t):BasicClass(t){};
~DeriveClass(){};
//重定义隐藏
void overloadFunc(int k){
cout<<"redefine overloadFunc from derived Class!"<<endl;
};
//重写
void overrideFunc(){
cout<<"overrideFunc From Derived Class!"<<endl;
};
}; int main(){
BasicClass b;
DeriveClass d; //重载
b.overloadFunc();
b.overloadFunc(,); //重写
d.overrideFunc();
b.overrideFunc(); //隐藏
b.overloadFunc();
d.overloadFunc();
return ;
}

程序输出:


四、虚函数调用机制

陈皓的C++虚函数表解析:http://blog.csdn.net/haoel/article/details/1948051/

C++中每一个对每一个类对象都维护一个虚函数表,里面记录了对应的函数入口指针,按照C++ Primer上所说,虚函数是实现多太的最核心部分,通过指针或者引用以及虚函数的动态绑定就可以方便的实现多态了,在以上程序中主函数中加入如下代码

//通过指针和引用实现动态绑定
cout<<"*********************动态绑定********************"<<endl;
BasicClass *pb=&d;
pb->overrideFunc();
pb->overloadFunc();
BasicClass &QuoteB=d;
QuoteB.overrideFunc();
QuoteB.overloadFunc(); cout<<"*********************静态绑定********************"<<endl;
BasicClass b1=d;
b1.overrideFunc();
b1.overloadFunc();

最终输出结果如下:

分析结果可一看出,动态绑定是运行时才决定调用哪个函数,通过指针过引用指向子类class对象从而实现多态,因此前两个overrideFunc输出是子类的结果;

但是父类对象直接被子类对象执行赋值操作,回导致隐式类型转换,将子类对象的基类部分复制给父类对象,并调用了父类对象的copy构造函数或者复制函数。

C++重写(override)、重载(overload)、重定义(redefine)以及虚函数调用的更多相关文章

  1. 重写(Override) 重载(Overload)

    重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变.即外壳不变,核心重写! 重载(Overload)- 参数必须不同 重载(overloadin ...

  2. C++重写与重载、重定义

    文章引用自:http://blog.163.com/clevertanglei900@126/blog/static/111352259201102441934870/ 重载overload:是函数名 ...

  3. (转)C++重写、重载和重定义的区别

    C++ 重写重载重定义区别 (源自:http://blog.163.com/clevertanglei900@126/blog/static/111352259201102441934870/) 1 ...

  4. C++ 重载(overload)、重写(overrride)、重定义(redefine)总结

    引自:http://www.189works.com/article-42111-1.html 先来看几个概念: 重载(overload),重写(override,也称覆盖), 重定义(redefin ...

  5. 重载(overload)、重写:覆盖(override)、重定义:遮蔽(redefine)、多态

    同一域名空间,函数名相同,签名不同 编译期绑定确定绑定函数,也称为静态多态 重写:覆盖(override) 虚函数 子类空间,函数名相同,签名相同 重定义:遮蔽(redefine) 非虚函数,子类成员 ...

  6. C++ 虚函数及重载、重定义、重写

    #include<iostream> usingnamespace std; class BASE { public: BASE()=default; BASE(int publicVal ...

  7. C++重写(覆盖)、重载、重定义、

    总结: 重写(覆盖)override 是指派生类函数重写(覆盖)基类函数 不同的范围,分别位于基类和派生类中 函数的名字相同 参数相同 基类函数必须有virtual关键字 重载overload 成员函 ...

  8. C++重写(覆盖)、重载、重定义、多态

    1 重写(覆盖)override override是重写(覆盖)了一个方法,以实现不同的功能.一般用于子类在继承父类时,重写(覆盖)父类中的方法.函数特征相同,但是具体实现不同. 重写需要注意: 被重 ...

  9. C++中重载、重定义、重写概念辨析

    重载:函数名相同,函数的参数个数.参数类型或参数顺序三者中必须至少有一种不同.函数返回值的类型可以相同,也可以不相同.发生在一个类内部. 重定义:也叫做隐藏.覆盖,子类重新定义父类中有相同名称的非虚函 ...

随机推荐

  1. 【Canvas】canva实例-星空、日出的效果

    一.描述 模仿星空后黎明到来,日出的场景 二.代码 <!DOCTYPE html> <html> <head> <title></title> ...

  2. div+css命名规范大全

    网页制作中规范使用DIV+CSS命名规则,可以改善优化功效特别是团队合作时候可以提供合作制作效率, 我们开发DIV+CSS网页(Xhtml)时候,比较困惑和纠结的事就是CSS命名,特别是新手不知道什么 ...

  3. ETL作业调度软件TASKCTL4.1集群部署

    熟悉TASKCTL4.1一段时间后,觉得它的调度逻辑什么的都还不错,但是感觉单机部署不太够用.想实现跨机调度作业,就要会TASKCTL的集群部署.下面就是我在网上找到的相关资料,非原创. 单机部署成功 ...

  4. Fiddler基础使用二之捕获手机应用https请求

    Fiddler是一款非常流行并且实用的http抓包工具,它的原理是在本机开启了一个http的代理服务器,然后它会转发所有的http请求和响应, 因此,它比一般的firebug或者是chrome自带的抓 ...

  5. akoj-1162-计算表达式

    计算表达式 Time Limit:1000MS  Memory Limit:65536K Total Submit:14 Accepted:7 Description 对于一个不存在括号的表达式进行计 ...

  6. [Scoi2014]方伯伯的玉米田 二维树状数组+动态规划

    考试最后半个小时才做这道题.十分钟写了个暴力还写挂了..最后默默输出n.菜鸡一只. 这道题比较好看出来是动规.首先我们要明确一点.因为能拔高长度任意的一段区域,所以如果从i开始拔高,那么一直拔高到n比 ...

  7. Loadrunner常见错误处理方法

    1.错误 -26601: 解压缩函数(wgzMemDecompressBuffer)失败,返回代码=-5 (Z_BUF_ERROR).inSize=0.inUse=0.outUse=0 用LR做压力测 ...

  8. php 下载文件

    <?php header("Content-type:text/html;charset=utf-8"); // $file_name="cookie.jpg&qu ...

  9. javascript+HTMl5游戏下载,开发一个都能月薪上万!舅服你

    HTML5时代已经到来许久了,你是否已经掌握了那么一点呢?今天小编给大家讲讲h5的折叠多设备.跨平台特性, 即用HTML5制作游戏.相比flash,HTML5更加灵活方便,随着浏览器技术的不断升级,H ...

  10. PHP基础与JS操作的区别

    嵌入页面方式 JS嵌入方式:<script></script> PHP嵌入方式:<?php ?>(常用) 输出语法 Javascript输出 1.alert(&qu ...