一、基本概念

对于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. Asp.net MVC Razor常见问题及解决方法

    没有经验的童鞋就是这样磕磕碰碰出来的经验. 1,Datatype的错误提示消息无法自定义 这也许是Asp.net MVC的一个Bug.ViewModel中定义了DataType为Date字段: [Re ...

  2. Web测试与APP测试有哪些异同?

    1.相同点 不管是传统行业的web测试,还是新兴的手机APP测试,都离不开测试的基础知识,即是不管怎么变,测试的原理依然会融入在这两者当中. 1)设计测试用例时,依然都是依据边界值分析法.等价类划分等 ...

  3. mk框架,一个基于react、nodejs全栈框架

    在这个前端技术爆炸的时代,不自己写套开源框架出门都不好意思跟别人打招呼,作为一个前端领域的小学生,去年年初接触了react,之后一发不可收拾爱上了它,近期重构了自己去年开源的一个项目,废话到此结束句号 ...

  4. Linux 下实时查看日志

    Linux 下实时查看日志 cat /var/log/*.log 如果日志在更新,如何实时查看 tail -f /var/log/messages 还可以使用 watch -d -n 1 cat /v ...

  5. JavaSE(五)JAVA对象向上转型和向下转型

    今天做了一个测试的题目,发现自己还是很多问题没有静下心来做.很多问题是可以自己解决的但是自己一是没有读清题意,二是自己心里太急躁了.所以这个要自己应以为鉴! 对象的转型问题其实并不复杂,我们记住一句话 ...

  6. [dubbo实战] dubbo+zookeeper伪集群搭建

    zookeeper作为注册中心,服务器和客户端都要访问,如果有大量的并发,肯定会有等待.所以可以通过zookeeper集群解决. 一.为什么需要zookeeper呢? 大部分分布式应用需要一个主控.协 ...

  7. centos7安装docker并安装jdk和tomcat(常用命令)

    阿里专属的镜像加速 在宿主机器编辑文件:vi /etc/docker/daemon.json 阿里专属的镜像加速地址,类似于"https://91cntlkt.mirror.aliyuncs ...

  8. 关于个人编辑器sublime text3使用指南

    用过了好多编辑器,前些年用的zend studio,phpstorm近两年转为nodepad++(因为写的语言种类比较多了,shell,python,php,前端等),相对于nodepad++,  s ...

  9. Ubuntu 虚拟机支持与windows机器复制粘贴

    实现虚拟机VMware上Ubuntu与主机windows之间互相复制与粘贴 实现VMware中Ubuntu与主机Windows系统之间的相互复制与粘贴(公用粘贴板): 1.在虚拟机VMware的菜单栏 ...

  10. selenium + ChromeDriver

    Selenium是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.而对于爬虫来说,使用Selenium操控浏览器来爬取网上的数据那么肯定是爬虫中的杀 ...