C++重写(override)、重载(overload)、重定义(redefine)以及虚函数调用
一、基本概念
对于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)以及虚函数调用的更多相关文章
- 重写(Override) 重载(Overload)
重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变.即外壳不变,核心重写! 重载(Overload)- 参数必须不同 重载(overloadin ...
- C++重写与重载、重定义
文章引用自:http://blog.163.com/clevertanglei900@126/blog/static/111352259201102441934870/ 重载overload:是函数名 ...
- (转)C++重写、重载和重定义的区别
C++ 重写重载重定义区别 (源自:http://blog.163.com/clevertanglei900@126/blog/static/111352259201102441934870/) 1 ...
- C++ 重载(overload)、重写(overrride)、重定义(redefine)总结
引自:http://www.189works.com/article-42111-1.html 先来看几个概念: 重载(overload),重写(override,也称覆盖), 重定义(redefin ...
- 重载(overload)、重写:覆盖(override)、重定义:遮蔽(redefine)、多态
同一域名空间,函数名相同,签名不同 编译期绑定确定绑定函数,也称为静态多态 重写:覆盖(override) 虚函数 子类空间,函数名相同,签名相同 重定义:遮蔽(redefine) 非虚函数,子类成员 ...
- C++ 虚函数及重载、重定义、重写
#include<iostream> usingnamespace std; class BASE { public: BASE()=default; BASE(int publicVal ...
- C++重写(覆盖)、重载、重定义、
总结: 重写(覆盖)override 是指派生类函数重写(覆盖)基类函数 不同的范围,分别位于基类和派生类中 函数的名字相同 参数相同 基类函数必须有virtual关键字 重载overload 成员函 ...
- C++重写(覆盖)、重载、重定义、多态
1 重写(覆盖)override override是重写(覆盖)了一个方法,以实现不同的功能.一般用于子类在继承父类时,重写(覆盖)父类中的方法.函数特征相同,但是具体实现不同. 重写需要注意: 被重 ...
- C++中重载、重定义、重写概念辨析
重载:函数名相同,函数的参数个数.参数类型或参数顺序三者中必须至少有一种不同.函数返回值的类型可以相同,也可以不相同.发生在一个类内部. 重定义:也叫做隐藏.覆盖,子类重新定义父类中有相同名称的非虚函 ...
随机推荐
- 【css】盒子模型 之 弹性盒模型
参考: http://caibaojian.com/flexbox-guide.html 待补充啊
- Javascript跨域后台设置拦截
子域名之间互相访问需要跨域 结论放在开头: 服务端必须设置允许跨域 客户端带cookie需要设置withCredentials 无论服务端是否允许跨域,该request都会完整执行 options预请 ...
- Java 字符串截取问题
编程:编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串. 但是要保证汉字不被截半个,如"我ABC"4 public class StringSplit ...
- Typescript 解构 、展开
什么是解构.展开? 展开与解构作用相反,简单来说: 解构:解构赋值允许你使用数组或对象字面量的语法,将数组和对象的属性付给各种变量. 展开:允许你讲一个数组展开为另一个数组,或一个对象展开为另一个对象 ...
- python实战第一天-环境的安装
操作系统 Ubuntu 15.10 IDE & editor JetBrains PyCharm 5.0.2 ipython3 Python版本 python-3.4.3 安装Python s ...
- 设计模式(2)--Singleton--单例模式--创建型
1.模式定义: 单例模式确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 2.模式特点: (1)单例类只能有一个实例. (2)单例类必须自己创建自己的唯一实例. (3)单例类必须给所有 ...
- Kettle安装和配置
0x01 Kettle软件概览 Spoon:集成开发环境 Kitchen:作业的命令行运行程序,可以通过Schell脚本来调用 Pan:转换的命令行程序 Carte:轻量级的HTTP服务,后台运行,监 ...
- 解析SS、SP、BP寄存器
SS, SP, BP 三个寄存器 SS:存放栈的段地址: SP:堆栈寄存器SP(stack pointer)存放栈的偏移地址; BP: 基数指针寄存器BP(base pointer)是一个寄存器,它的 ...
- 关于视频编辑SDK的接入说明
一.运行环境 Android 4.1(api 16)以上: 处理器:双核 1GHz以上CPU(目前只支持ARM CPU, X86.MIPS暂不支持):推荐四核1.2GHz以上CPU 内存:1 GB以上 ...
- js的点表示法和方括号表示法
最近发现了一个很好玩的js特性,就是任何可以用点表示法的语句,都可以同样用方括号表示法表示出来,就例如一下语句,三句都是可以实现的: document.body.innerHTML="tes ...