C++隐藏规则
在面向对象的开发过程中,经常出现类的继承,这里面出现的成员函数的重载(overload)、覆盖(override)与隐藏(hidden)很容易混淆。
首先澄清这3个概念:
重载
- 相同的范围(在同一个类中)
- 函数名字相同
- 参数不同
- virtual 关键字可有可无
覆盖(派生类函数覆盖基类函数)
- 不同的范围(分别位于派生类与基类)
- 函数名字相同
- 参数相同
- 基类函数必须有 virtual 关键字
隐藏(派生类的函数屏蔽了与其同名的基类函数)
- 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载混淆)
- 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有 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指向同一地址,按理运行结果是相同的,但其实却不是。由于隐藏机制的作用,部分方法的调用依赖于所使用的指针!
由此看来,隐藏机制似乎会带来不少理解上的问题,但“存在即合理”:
- 写语句pd->f(10)的人可能真的想调用Derived::f(char *)函数,只是他误将参数写错了。有了隐藏规则,编译器就可以明确指出错误,这未必不是好事。否则,编译器会静悄悄地将错就错,程序员将很难发现这个错误,留下祸根
- 假如类Derived有多个基类(多重继承) ,有时搞不清楚哪些基类定义了函数f。如果没有隐藏规则,那么pd->f(10)可能会调用一个出乎意料的基类函数f,而隐藏规则的存在消灭了这个问题
总结
工欲善其事,必先利其器。弄清楚这些基本概念,才能在实践中少走弯路。
http://www.cnblogs.com/roucheng/p/3470287.html
C++隐藏规则的更多相关文章
- makefile中重载与取消隐藏规则示例
学习<跟我一起写Makefile-陈皓>后一直不懂,如何重载或取消隐藏规则 为了博客版面整洁,何为隐藏规则,Makefile基本规则编写等基础支持请自行百度. 需要声明的是:这些知识可能在 ...
- c++中的重载(Overload)、覆盖(重写,Override) 、隐藏与using声明
这些概念有时记住了,但可能没多久就忘了,还是记下来吧.网上找的一篇不错:这里 1 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中,不包括继承来的): (2)函数名字相同: (3) ...
- Java 隐藏和覆盖
我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊 ...
- c/c++:重载 覆盖 隐藏 overload override overwrite
http://www.cnblogs.com/qlee/archive/2011/07/04/2097055.html 成员函数的重载.覆盖与隐藏成员函数的重载.覆盖(override)与隐藏很容易混 ...
- c++虚函数,纯虚函数,抽象类,覆盖,重载,隐藏
C++虚函数表解析(转) ——写的真不错,忍不住转了 http://blog.csdn.net/hairetz/article/details/4137000 浅谈C++多态性 http://bl ...
- c++中的隐藏、重载、覆盖(重写)
转自c++中的隐藏.重载.覆盖(重写) 1 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual关键字可有可无. 覆盖是 ...
- C++ 过载,重写,隐藏
1.过载:在一个类中(也就是一个作用域),方法名相同,形参表不同的方法. 2.重写:父类方法使用virtual,子类方法和方法的方法名,形参表,返回类型相同,子类可以不使用virtual,但是建议使用 ...
- 【转】c++重载、覆盖、隐藏——理不清的区别
原文网址:http://blog.sina.com.cn/s/blog_492d601f0100jqqm.html 再次把林锐博士的<高质量c++编程指南>翻出来看的时候,再一次的觉得这是 ...
- C++ Virtual详解(注意函数被隐藏的问题)
Virtual是C++ OO机制中很重要的一个关键字.只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就 ...
随机推荐
- ps中如何用抽出功能扣取头发
一些图片中需要扣取人的头发,非常不好扣,本文介绍抽取扣除 打开一个人物图片,用ctrj+j分别复制几个图层,从下往上分别为:背景副本,图层2(用于修改成别的背景),图层1抽头发白色(用于抽头发,强制前 ...
- How to import library ?
Android Studio: Download or git the library. (for example: the library folder named ActionBarSherloc ...
- Console中加入招聘等个性化信息
try { if (window.console && window.console.log) { console.log("%c XX息科技 ", "f ...
- 数据仓库专题(23):总线矩阵的另类应用-Drill Down into a More Detailed Bus Matrix
一.前言 Many of you are already familiar with the data warehouse bus architecture and matrix given thei ...
- JSON处理
var ajax = function () { mui.ajax(projectPath+'/goods/goodsprice.do', { dataType: 'json', type: 'pos ...
- 一种线程安全的handle
对象引用的正确性在多线程环境下是一个复杂的问题,请参考,处理由引用计数引起的泄漏.简单来说,我们应该尽量减少使用强引用,否则将有可能产生[处理由引用计数引起的泄漏]一文中描述的难以察觉的内存泄漏问题. ...
- [原]quick集成spine动画
更新说明: 新增了骨骼绑定node用法 参考:http://blog.csdn.net/n5/article/details/21795265 在SkeletonRenderer.h 和cpp里面新加 ...
- 轻量级容器Docker+微服务+RESTful API
[宗师]李锟(44035001) 10:23:03感觉Docker这样的轻量级容器+微服务+RESTful API三者可以形成一个铁三角.这也代表了PaaS未来的发展方向. [宗师]李锟(440350 ...
- 网上收集的以及自己总结的iOS开发技巧
Objective-C 1.让Xcode的控制台支持LLDB类型的打印 这有什么用? 怎么说尼,笔者认为这个还是比较有用滴,为什么有用尼? 因为在Xcode断点调试的时候, 在控制台输入 po sel ...
- bower 新建.bowerrc文件
Twitter工程师团队推出了Bower,这是一个针对Web开发的包管理器.该工具主要用来帮助用户轻松安装CSS.JavaScript.图像等相关包,并管理这些包之间的依赖. 随着网页功能变得越来越复 ...