C++ ------ 虚函数覆盖、重载
在C++语言中,虚函数是非常重要的概念,虚函数是实现C++面向对象中多态性和继承性的基石。而多态性和继承性则是面向对象语言的精髓。掌握虚函数才算是真正掌握C++语言,而C++语言中虚函数的继承覆盖与函数重载有些类似,很多初学者搞不清他们之间的关系。
首先要明确覆盖(override)与重载(overload)的定义,区别出什么是覆盖和重载:
覆盖就是派生类中虚成员函数覆盖基类中同名且参数相同的成员函数。
如下例:
上例中,CDerived和CBase之间就是函数覆盖关系,Walk和Jump函数被派生类覆盖,输出肯定是派生类函数的输出。下面就这几者关系着重学习。再看看下例:
class CBase
{
public:
CBase();
virtual void Walk(){cout<<"CBase:Walk"<<endl;}
virtual void Jump(){cout<<"CBase:Jump"<<endl;}
void Run(int speed){cout<<"CBase:Run:"<<"Speed="<<speed<<endl;}
};
class CDerivedA : public CBase
{
public:
CDerivedA();
void Walk(){cout<<"CDerivedA:Walk"<<endl;}
void Jump(){cout<<"CDerivedA:Jump"<<endl;}
void Run(int speed) {cout<<"CDerivedA:Run"<<"Speed="<<speed<<endl;}
};
int main()
{
CBase *pTmp1=new CDerivedA ;
pTmp1->Walk();
pTmp1->Run();
return ;
}
这里基类中Run与派生类中Run函数就是重载(overload)关系,当使用基类来调用派生类对象中重载函数,会根据其作用域来判断,如基类CBase,其作用域就是CBase这个类的大括号包含的内容,派生类CDeriverdA其作用域就是CDerivedA大括号中包含的内容。因此在使用基类调用派生类对象中的Run方法时,会执行基类的Run方法。
关于作用域可见性规则(摘于网上:http://www.51laifu.cn/archives/2012/610/article-31092.html)如下:
如果存在两个或多个具有包含关系的作用域,外层声明了一个标识符,而内层没有再次声明同名标识符,那么外层标识符在内层依然可见,如果在内层声明了同名标识符,则外层标识符在内层不可见,这时称内层标识符隐藏了外层同名标识符,这种现象称为隐藏规则。
在类的派生层次结构中,基类的成员和派生类新增的成员都具有类作用域。二者的作用范围不同,是相互包含的两个层,派生类在内层。这时,如果派生类声明了一个和某个基类成员同名的新成员,派生的新成员就隐藏了外层同名成员,直接使用成员名只能访问到派生类的成员。如果派生类中声明了与基类同名的新函数,即使函数的参数表不同,从基类继承的同名函数的所有重载形式也都被隐藏。如果要访问被隐藏的成员,就需要使用类作用域分辨符和基类名来限定。
根据上面的解释,CBase类处于作用域的外层,因此派生类的方法对于其将是不可见的,即隐藏的。而在派生类中,如果有重载函数时,基类函数将会被隐藏,否则基类函数就不被隐藏。
函数重载和虚函数都能实现对象的多态特性,但是函数重载只能实现静态的多态,也就是在编译时多态,即编译器会给重载的函数在编译时加上不同的前缀,是函数名在运行时不同。而虚函数可以实现动态多态,即运行时多态,但是虚函数实现需要增加额外的虚函数指针等,会增加相应空间。
再看下例:
以上代码就可以看出,派生类中的重载方法,在基类是不能调用的,编译的时候就会出错。
C++ ------ 虚函数覆盖、重载的更多相关文章
- C++基础:虚函数、重载、覆盖、隐藏<转>
转自:http://www.2cto.com/kf/201404/291772.html 虚函数总是跟多态联系在一起,引入虚函数可以使用基类指针对继承类对象进行操作! 虚函数:继承接口(函数名,参数, ...
- C++ 虚函数及重载、重定义、重写
#include<iostream> usingnamespace std; class BASE { public: BASE()=default; BASE(int publicVal ...
- 虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底
为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针. 也可以将基类的非静态成员函数定义为虚函数(在函数前加上virtual) #include<iostream> usi ...
- c++ 多态,虚函数、重载函数、模版函数
c++三大特性:封装.继承.多态.封装使代码模块化,继承扩展已存在的代码,多态的目的是为了接口重用 虚函数实现:虚函数表:指针放到虚函数表 多态:同名函数对应到不同的实现 构造父类指针指向子类的对象 ...
- c++虚函数与重载
class base{ public: virtual void f(int n){ cout << "base"<<endl; } }; class De ...
- c++运算符重载和虚函数
运算符重载与虚函数 单目运算符 接下来都以AClass作为一个类例子介绍 AClass{ int var } 区分后置++与前置++ AClass operator ++ () ++前置 一般设计为返 ...
- C++ 基础语法 快速复习笔记(3)---重载函数,多态,虚函数
1.重载运算符和重载函数: C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它 ...
- C++ 派生类函数重载与虚函数继承详解
目录 一.作用域与名字查找 1.作用域的嵌套 2.在编译时进行名字查找 3.名字冲突与继承 4.通过作用域运算符来使用隐藏的成员 二.同名函数隐藏与虚函数覆盖 1.几种必须区分的情况 2.一个更复杂的 ...
- c/c++ 基金会(七) 功能覆盖,虚函数,纯虚函数控制
1.功能覆盖 ClassA , ClassB ,其中ClassB继承ClassA 类的定义如下面的: #ifndef _CLASSA_H #define _CLASSA_H #include < ...
随机推荐
- Paper Reading - Attention Is All You Need ( NIPS 2017 ) ★
Link of the Paper: https://arxiv.org/abs/1706.03762 Motivation: The inherently sequential nature of ...
- less 语法特性翻译稿 - 特性快速预览部分
原文地址 http://lesscss.cn/features/ 概述 作为CSS的一种扩展语法,Less不仅仅向后兼容CSS,新的特性也是基于CSS现有语法.这使得学习Less变得容易,如果你有所怀 ...
- 用 Python 3 的 async / await 做异步编程
前年我曾写过一篇<初探 Python 3 的异步 IO 编程>,当时只是初步接触了一下 yield from 语法和 asyncio 标准库.前些日子我在 V2EX 看到一篇<为什么 ...
- USACO 2.3.3 Zero Sum 和为零(深搜枚举)
Description 请考虑一个由1到N(N=3, 4, 5 ... 9)的数字组成的递增数列:1 2 3 ... N. 现在请在数列中插入“+”表示加,或者“-”表示减,抑或是“ ”表示空白,来将 ...
- Scrum立会报告+燃尽图(十一月二十三日总第三十一次):界面修改及新页面添加
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2410 项目地址:https://git.coding.net/zhang ...
- Scrum立会报告+燃尽图(Beta阶段第二周第四次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2412 项目地址:https://coding.net/u/wuyy694 ...
- Requests库常用方法及其详解
request库七个方法详解 1. request方法 所有方法的的基础方法,三个参数:method,url,**kwargs. 1.1 method:请求方式 method参数共有七个可选的值,分别 ...
- Maya脚本——重命名物体的名称
该脚本用于将图1中的命名变更为图2中的,把maya中使用相同名称的物体都重命名为不同的名称. 重命名的规则是:组名_原名称_序号 查阅了maya的官方手册:http://download.autode ...
- Servlet中常用对象及API类之间的关系
Servlet最常用的对象: 请求对象:ServletRequest和HttpServletRequest,通过该对象获取来自客户端的请求信息 响应对象:ServletResponse和HttpSer ...
- Haproxy + Rabbit 集群 简要介绍
# 两台主机都安装上rabbitMQ yum install -y rabbitmq-server # 两台主机都配置/etc/hosts文件 192.168.23.10 rabbitmq1 19 ...