在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++ ------ 虚函数覆盖、重载的更多相关文章

  1. C++基础:虚函数、重载、覆盖、隐藏<转>

    转自:http://www.2cto.com/kf/201404/291772.html 虚函数总是跟多态联系在一起,引入虚函数可以使用基类指针对继承类对象进行操作! 虚函数:继承接口(函数名,参数, ...

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

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

  3. 虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底

    为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针. 也可以将基类的非静态成员函数定义为虚函数(在函数前加上virtual) #include<iostream> usi ...

  4. c++ 多态,虚函数、重载函数、模版函数

    c++三大特性:封装.继承.多态.封装使代码模块化,继承扩展已存在的代码,多态的目的是为了接口重用 虚函数实现:虚函数表:指针放到虚函数表 多态:同名函数对应到不同的实现 构造父类指针指向子类的对象 ...

  5. c++虚函数与重载

    class base{ public: virtual void f(int n){ cout << "base"<<endl; } }; class De ...

  6. c++运算符重载和虚函数

    运算符重载与虚函数 单目运算符 接下来都以AClass作为一个类例子介绍 AClass{ int var } 区分后置++与前置++ AClass operator ++ () ++前置 一般设计为返 ...

  7. C++ 基础语法 快速复习笔记(3)---重载函数,多态,虚函数

    1.重载运算符和重载函数: C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它 ...

  8. C++ 派生类函数重载与虚函数继承详解

    目录 一.作用域与名字查找 1.作用域的嵌套 2.在编译时进行名字查找 3.名字冲突与继承 4.通过作用域运算符来使用隐藏的成员 二.同名函数隐藏与虚函数覆盖 1.几种必须区分的情况 2.一个更复杂的 ...

  9. c/c++ 基金会(七) 功能覆盖,虚函数,纯虚函数控制

    1.功能覆盖 ClassA , ClassB ,其中ClassB继承ClassA 类的定义如下面的: #ifndef _CLASSA_H #define _CLASSA_H #include < ...

随机推荐

  1. AOP:静态代理实现方式①通过继承②通过接口

    文件结构: 添加日志: package com.wangcf.manager; public class LogManager { public void add(){ System.out.prin ...

  2. 福大软工1816:Beta总结

    第三视角Beta答辩总结 博客链接以及团队信息 组长博客链接 成员信息(按拼音排序) 姓名 学号 备注 张扬 031602345 组长 陈加伟 031602204 郭俊彦 031602213 洪泽波 ...

  3. c语言的知识与能力自评

    知识与能力 C语言最早是由美国Bell实验室设计的,主要用作UNIX系统的工作语言,后来发展成为一种通用语言.C与UNIX有密切的关系,C最早是在PDP机器上用UNIX操作系统上开发的,后来又用C语言 ...

  4. 转 下一代云计算模式:Docker正掀起个性化商业革命

    下一代云计算模式:Docker正掀起个性化商业革命 作者: 吴宁川  来源: ITValue  发布时间: 2015-09-20 10:41  阅读: 14052 次  推荐: 26   原文链接   ...

  5. 201621123037 《Java学习设计》 第五周学习总结

    Week05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键词:接口."has-a".多态.comparable.Compa ...

  6. PAT 甲级 1063 Set Similarity

    https://pintia.cn/problem-sets/994805342720868352/problems/994805409175420928 Given two sets of inte ...

  7. [CB] Windows10为什么质量变差 bug越来越多

    在 Windows 10 发布之后,微软转向了软件即服务模式,每半年释出一个新版本,通过增加更新频率将新的特性不断推送给用户. 在以前,微软产品发布周期是两到三年,其开发流程分成多个阶段:设计和策划. ...

  8. javascript 常用知识点

    1:浏览器是有缓存的,开发中可以通过快捷键绕过缓存 对于Windows驱动的系统:Ctrl + F5 对于Mac驱动的系统:Command + Shift + R. 2:精度问题 (符点和大数字可能会 ...

  9. jmeter 兼容bug 记录一笔

    这个问题我也遇到过,然后网上搜到了这篇文章! 先说下问题: 我在做性能测试时,使用JMeter搞了100个并发,以100TPS的压力压测十分钟,但压力一直出现波动,而且出现波动时JMeter十分卡,如 ...

  10. C#中的静态常量(const)和动态常量(static和readonly)用法和区别

    C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量),本文将就这两种类型的不同特性进行比较并说明各自的适用场景.工作原理 readonly为运行时常量,程序运行时进行赋 ...