C++ 虚函数及重载、重定义、重写
#include<iostream>usingnamespace std;class BASE{public:BASE()=default;BASE(int publicValue,int protectedVale,int privateValue){this->publicValue = publicValue;this->protectedValue = protectedVale;this->privateValue = privateValue;}virtualint getPubValue(int value =0){cout <<"BASE"<< endl;publicValue = value;return publicValue;}/**< 注意不是virtual函数 */int getProValue(){return protectedValue;}public:int publicValue;protected:int protectedValue;private:int privateValue;};class INHERT :public BASE{public:INHERT(int pubValue,int proValue,int priValue):BASE(pubValue, proValue, priValue){}/**< 访问从父类继承的public成员 */int getPubValue(int value =1) override{cout <<"INHERT"<< endl;publicValue = value;return publicValue;}/**< 访问从父类继承的protected成员 */// int getProValue()// {// return protectedValue;// }/**< 从父类继承来的private成员,在子类中是不可访问的。*/// int getPriValue()// {// return privateValue;// }/**< 将会隐藏基类中的同名函数,与参数类型或者参数的顺序无关 */int getProValue(int value){protectedValue = value;return protectedValue;}/**< 通过添加using BASE::getProValue; 将基类所有getProValue函数的重载版本添加到派生类的作用域中去*//**< 在派生类中可以添加新的重载版本,或者覆盖已有的重载版本 */using BASE::getProValue;};int main(){INHERT inhert(4,5,6);BASE * base =&inhert;/**< 虽然调用的是派生类的getPubValue()函数,但是由于该函数在基类和派生类中都带有默认值,所以该函数使用的是基类中的默认值 */cout << base->getPubValue()<< endl;/**< 由于在派生类中重新定义了getProValue函数,则从父类继承的getProValue()将会被隐藏*///cout << inhert.getProValue() << endl;cout << inhert.getProValue(100)<< endl;/**< 显式调用被隐藏函数 */cout << inhert.BASE::getProValue()<< endl;/**< 通过添加using BASE::getProValue; 将基类所有getProValue函数的重载版本添加到派生类的作用域中去*//**< 在派生类中可以添加新的重载版本,或者覆盖已有的重载版本 */cout << inhert.getProValue()<< endl;return0;}
1 在C++中,有以下几个概念
重定义(redefine):派生类对基类的成员函数重新定义(即派生类定义了某个函数)该函数的名字与基类中的函数名字一样。
重载(overload):函数名字相同,但它的形参个数或者顺序(或者类型不同)注意不能靠返回类型来判断。
重写(override):派生类重定义基类的虚函数(即会覆盖基类的虚函数)。
如果在派生类中定义了一个与基类同名的函数,不管这个函数的参数列表是不是与基类中的函数相同,则这个同名的函数就会把基类中的所有这个同名的函数的所有重载版本都隐藏了,这时并不是在派生类中重载基类的同名成员函数,而是隐藏。
比如你的基类中有一个成员函数:void func(int i);而子类中又定义了一个void func();那么此时,基类中的void func(int i)就被自动隐藏了,子类对象不能直接调用它。
覆盖:(特征标全部相同的虚函数-原型相同)
如果派生类覆盖了基类中的成员函数或成员变量,则当派生类的对象调用该函数或变量时是调用的派生类中的版本,当用基类对象调用该函数或变量时是调用的基类中的版本。
2 怎样使用派生类的对象访问基类中被派生类覆盖或隐藏了的函数或变量
方法 1 使用作用域运算符:
在使用对象调用基类中的函数或变量时使用作用域运算符即语句 m.A::f(2),这时就能访问基类中的函数或变量版本。
注意,访问基类中被派生类覆盖了的成员变量只能用这种方法
方法 2 使用 using:
该方法只适用于被隐藏或覆盖的基类函数,在派生类的类声明中使用语句 using 把基类的名字包含进来(注意子类的重定义),比如using A::f;就是将基类中的函数f()的所有重载版本包含进来,重载版本被包含到子类之后,这些重载的函数版本就相当于是子类的一部分,这时就可以用派生类的对象直接调用被派生类隐藏了的基类版本,比如 m.f(2),但是使用这种语句还是没法调用基类在派生类中被覆盖了的基类的函数,比如 m.f()调用的是派生类中定义的函数f,要调用被覆盖的基类中的版本要使用语句m.A::f()才行。
在派生类的函数中调用基类中的成员变量和函数的方法:就是在函数中使用的被派生类覆盖的基类成员变量或函数
前用作域解析符加上基类的类名,即a::f()就是在派生类的函数中调用基类中被派生类覆盖了的函数f()的方法。
派生类以私有方式被继承时改变基类中的公有成员为公有的方法:
使用::作用域运算符,不提倡用这种方法,在派生类的 public 后面用作用域运算符把基类的 公有成员包含进来,这样基类的成员就会成为派生类中的公有成员了,注意如果是函数的 话后面不能加括号 ,如A::f;如果f是函数的话不能有括号。
使用using语句,现在一般用这种方法,也是在派生类的public使用using把基类成员包函进来,如using A::f。
3 如何设计类函数
对于希望子类重写的函数,也就是说基类可以提供自己的一份实现或者不提供实现,但是子类必须拥有自己的实现。一般采用虚函数或者纯虚函数;
对于一般的成员函数,在子类中不要进行重新定义,一般继承父类的实现即可;
C++ 虚函数及重载、重定义、重写的更多相关文章
- C++学习笔记 封装 继承 多态 重写 重载 重定义
C++ 三大特性 封装,继承,多态 封装 定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对 ...
- c++ 多态,虚函数、重载函数、模版函数
c++三大特性:封装.继承.多态.封装使代码模块化,继承扩展已存在的代码,多态的目的是为了接口重用 虚函数实现:虚函数表:指针放到虚函数表 多态:同名函数对应到不同的实现 构造父类指针指向子类的对象 ...
- 虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底
为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针. 也可以将基类的非静态成员函数定义为虚函数(在函数前加上virtual) #include<iostream> usi ...
- C++基础:虚函数、重载、覆盖、隐藏<转>
转自:http://www.2cto.com/kf/201404/291772.html 虚函数总是跟多态联系在一起,引入虚函数可以使用基类指针对继承类对象进行操作! 虚函数:继承接口(函数名,参数, ...
- c++虚函数与重载
class base{ public: virtual void f(int n){ cout << "base"<<endl; } }; class De ...
- Visual Studio编译时报错“函数名:重定义;不同的基类型”
错误原因: 方法在还未声明的地方就使用了.由于使用的地方与定义的地方都是在同一个.c文件中,所以没有报未声明的错误. 解决方法: 把实现放到使用的前面,或者在include语句和宏定义后面加上函数声明 ...
- 重载重写重定义-易混淆概念-C++编译器处理方式
1.函数重载 1)必须在同一个类中进行. 2)子类无法重载父类的函数,父类同名函数将被名称覆盖 3)重载是在编译期间根据参数类型和个数决定函数调用 2.函数重写 1)必须发生于父类与子类之间 2)并且 ...
- <转>C++继承中虚函数的使用
转自:http://blog.csdn.net/itolfn/article/details/7412364 一:继承中的指针问题. 1. 指向基类的指针可以指向派生类对象,当基类指针指向派生类对 ...
- C++ 类的多态二(函数重载--函数重写--函数重定义)
//函数重载--函数重写--函数重定义 #include<iostream> using namespace std; /* 函数重载: 必须在一个类中进行(子类无法重载父类中的函数) 子 ...
随机推荐
- App统计指标定义
度量(指标) 定义 活跃用户 指启动应用的用户(去重,即1台设备打开多次会被计为1个活跃用户). 是衡量一个应用运营情况最基础的一个指标,用以表示用户规模.通常根据不同的时间限定,有日活跃用户.周活跃 ...
- error: failed to connect to the hypervisor error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory 解决办法
服务器版本:CentOS Linux release 7.4 Linux lb 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x8 ...
- K8S从私有仓库拉取镜像
通常来讲,我们在通过公共镜像仓库拉取docker镜像的时候,不需要任何的认证操作,但我们在构建了企业的私有镜像以后,就不得不在拉取镜像之前通过用户名密码来完成认证. 在docker单机环境中,我们可以 ...
- 科学计算三维可视化---TraitsUI的介绍
TraitsUI的介绍 Python中存在Tkinter,wxPython,pyQt4等GUI图像界面编写库,这三类库要求程序员掌握众多的GUI API函数 对于科学计算的应用来说,我们希望可以快速的 ...
- 递归和静态static
function sum($n){ if($==1){ return 1; } return $n+sum($n-1); } echo sum(100); ---------------------- ...
- 2017 清北济南考前刷题Day 2 morning
期望得分:100+30+60=190 实际得分:100+30+30=160 T1 最优方案跳的高度一定是单调的 所以先按高度排序 dp[i][j] 跳了i次跳到j 枚举从哪儿跳到j转移即可 #incl ...
- ZeroMQ API(七) 安全
1.无安全性:zmq_null(7) 1.1 名称 zmq_null - 没有安全性或机密性 1.2 概要 NULL机制由ZMTP 3.0规范定义:http://rfc.zeromq.org/spec ...
- 网络爬虫框架Heritrix中Modules的各项说明
1)Select Crawl Scope:Crawl Scope 用于配置当前应该在什么范围内抓取网页链接.例如选择 BroadScope 则表示当前的抓取范围不受限制,选择 HostScope 则表 ...
- 让PHPCms内容页支持JavaScript的修改方法
在文件..\caches\caches_model\caches_data\content_input.class.php中找到函数: function get($data,$isimport = 0 ...
- Eclipse配置C++环境
由于实在不想用(界面太丑,超级强迫症),前段时间JAVA一直用eclipse,感觉这个IDE非常友好,看上去很舒服,下载的时候发现有C++版本,于是折腾了一会儿,谷歌上发现好多教程,但是大部分比较老, ...