在面向对象的开发过程中,经常出现类的继承,这里面出现的成员函数的重载(overload)、覆盖(override)与隐藏(hidden)很容易混淆。

首先澄清这3个概念:

重载

  1. 相同的范围(在同一个类中)
  2. 函数名字相同
  3. 参数不同
  4. virtual 关键字可有可无

覆盖(派生类函数覆盖基类函数)

  1. 不同的范围(分别位于派生类与基类)
  2. 函数名字相同
  3. 参数相同
  4. 基类函数必须有 virtual 关键字

隐藏(派生类的函数屏蔽了与其同名的基类函数)

  1. 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载混淆)
  2. 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

下面用一个简单的例子来阐述

#include <iostream>
using namespace std;
class Base
{
public:
virtual void vf(float x) { cout << "Base::vf(float) " << x << endl; }
void g(float x) { cout << "Base::g(float) " << x << endl; }
void h(float x) {cout << "Base::h(float) " << x << endl; }
};
class Derived : public Base
{
public:
virtual void vf(float x) { cout << "Derived::vf(float) " << x << endl; }
void g(int x) { cout << "Derived::g(int) " << x << endl; }
void h(float x) { cout << "Derived::h(float) " << x << endl; }
};
// http://www.cnblogs.com/roucheng/
int main()
{
Derived d;
Base *pb = &d;
Derived *pd = &d;
// Good : behavior depends solely on type of the object
pb->vf(3.14); // Derived::vf(float) 3.14
pd->vf(3.14); // Derived::vf(float) 3.14
// Bad : behavior depends on type of the pointer
pb->g(3.14); // Base::g(float) 3.14
pd->g(3.14); // Derived::g(int) 3 (suprise!)
// Bad : behavior depends on type of the pointer
pb->h(3.14); // Base::h(float) 3.14 (suprise!)
pd->h(3.14); // Derived::h(float) 3.14
return ;
}

例子中,pb和pd指向同一地址,按理运行结果是相同的,但其实却不是。由于隐藏机制的作用,部分方法的调用依赖于所使用的指针!

由此看来,隐藏机制似乎会带来不少理解上的问题,但“存在即合理”:

  1. 写语句pd->f(10)的人可能真的想调用Derived::f(char *)函数,只是他误将参数写错了。有了隐藏规则,编译器就可以明确指出错误,这未必不是好事。否则,编译器会静悄悄地将错就错,程序员将很难发现这个错误,留下祸根
  2. 假如类Derived有多个基类(多重继承) ,有时搞不清楚哪些基类定义了函数f。如果没有隐藏规则,那么pd->f(10)可能会调用一个出乎意料的基类函数f,而隐藏规则的存在消灭了这个问题

总结

工欲善其事,必先利其器。弄清楚这些基本概念,才能在实践中少走弯路。

http://www.cnblogs.com/roucheng/p/3470287.html

C++隐藏规则的更多相关文章

  1. makefile中重载与取消隐藏规则示例

    学习<跟我一起写Makefile-陈皓>后一直不懂,如何重载或取消隐藏规则 为了博客版面整洁,何为隐藏规则,Makefile基本规则编写等基础支持请自行百度. 需要声明的是:这些知识可能在 ...

  2. c++中的重载(Overload)、覆盖(重写,Override) 、隐藏与using声明

    这些概念有时记住了,但可能没多久就忘了,还是记下来吧.网上找的一篇不错:这里  1 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中,不包括继承来的): (2)函数名字相同: (3) ...

  3. Java 隐藏和覆盖

    我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊 ...

  4. c/c++:重载 覆盖 隐藏 overload override overwrite

    http://www.cnblogs.com/qlee/archive/2011/07/04/2097055.html 成员函数的重载.覆盖与隐藏成员函数的重载.覆盖(override)与隐藏很容易混 ...

  5. c++虚函数,纯虚函数,抽象类,覆盖,重载,隐藏

    C++虚函数表解析(转) ——写的真不错,忍不住转了  http://blog.csdn.net/hairetz/article/details/4137000 浅谈C++多态性  http://bl ...

  6. c++中的隐藏、重载、覆盖(重写)

    转自c++中的隐藏.重载.覆盖(重写) 1 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual关键字可有可无. 覆盖是 ...

  7. C++ 过载,重写,隐藏

    1.过载:在一个类中(也就是一个作用域),方法名相同,形参表不同的方法. 2.重写:父类方法使用virtual,子类方法和方法的方法名,形参表,返回类型相同,子类可以不使用virtual,但是建议使用 ...

  8. 【转】c++重载、覆盖、隐藏——理不清的区别

    原文网址:http://blog.sina.com.cn/s/blog_492d601f0100jqqm.html 再次把林锐博士的<高质量c++编程指南>翻出来看的时候,再一次的觉得这是 ...

  9. C++ Virtual详解(注意函数被隐藏的问题)

    Virtual是C++ OO机制中很重要的一个关键字.只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就 ...

随机推荐

  1. C# 百度语音合成

    语音合成及TTS,我们尝试使用百度的语音合成技术 不过我发现 有一种缺点在于没有离线包让我有些很不舒服,可能是在线版的 原因微软语音识别技术在Windows 2000是默认集成在系统组件中 或许我们不 ...

  2. BW标准数据源初始化设置

    在安装了一干补丁和做好了BW与R3的链接之后(此处有BISIS操心,具体事宜不详),我们就可以登录到R3系统看个究竟了. 磨刀不误砍柴工,先检查一下两边系统的补丁: R3端如下, ,貌似我们是19,通 ...

  3. 太阳升起并下落的小动画-SWIFT

    一个小小的动画,太阳公公上山又下山.先上效果图. 用 lipecap 录的gif效果有点卡顿.好吧,说下如何实现的. 首先在一个大圆内先计算出内切九边形各个顶点的位置,接着连接相应的顶点变成一个九角星 ...

  4. Spring进阶教程之在ApplicationContext初始化完成后重定义Bean

    前言 很久没有写博客了,也是两个原因:一是自己觉得一直在班门弄斧,其实自己没什么技术可言:二是很多朋友的问题实际上可以自行解决,我经常觉得不该我来过问,或者是有时候我认为技术还得靠自己钻研,我一两句话 ...

  5. node-sass 安装卡在 node scripts/install.js 解决办法

    转自:https://segmentfault.com/a/1190000005921721 ======== 7月12日更新 ======== 总的来说就是两种方法解决: SASS_BINARY_S ...

  6. Oracle Purchasing QUESTIONS AND ANSWERS

    Topic Summary Topic: CORRECTIONS: Corrections Topic: DELIVER: Receiving Delivery Topic: DROPSHIP: Dr ...

  7. SNF开发平台WinForm之六-上传下载组件使用-SNF快速开发平台3.3-Spring.Net.Framework

    6.1运行效果: 6.2开发实现: 1.先在要使用的项目进行引用,SNF.WinForm.Attachments.dll文件. 2.在工具箱内新建选项卡->选择项,浏览找到文件SNF.WinFo ...

  8. [转]Visual Studio技巧之打造拥有自己标识的代码模板

    可能经过很多博客的介绍,大家都知道代码段的使用,使用代码段可以很方便地生成一些常用的代码格式,确实对我们开发很方便.在团队开发中或者在某些情况下我们经常可能还会希望使用Visual Studio生成的 ...

  9. Shader Overview

    Unity有三种形式的Shader: (1)Surface Shaders:对光照管线的高层抽象,受光照和影子效果影响的shader,使用Cg/HLSL语言编写:不进行light相关操作的shader ...

  10. codeforces A. Bayan Bus(简单模拟)

    #include <queue> #include <string> #include <cstdio> #include <cstring> #inc ...