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中就 ...
随机推荐
- 火狐 SSL 收到了一个弱临时 Diffie-Hellman 密钥的解决办法
连接 https网址 时发生错误. 在服务器密钥交换握手信息中 SSL 收到了一个弱临时 Diffie-Hellman 密钥. (错误码: ssl_error_weak_server_ephemera ...
- Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java
Google面试题 股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值). SOLUTION 1: 1.维持两个h ...
- CSS-JQUERY笔记
Ready $(document).ready(function(){ }) Input_div_span Input-长度限制 <input maxLength="2"&g ...
- [leetcode]Combine Two Tables
leetcode竟然有sql的题了..两道简单的应该会做 这个题主要就是一个left join... # Write your MySQL query statement below SELECT P ...
- C#壓縮文件幫助類 使用ICSharpCode.SharpZipLib.dll
using ICSharpCode.SharpZipLib.Checksums; using ICSharpCode.SharpZipLib.Zip; using System; using Syst ...
- Android之layout_alignBottom失效问题
外面是一层RelativeLayout,前面的text和后面按钮都是设置centerParent_vertical,第二个hello是需要与第一个底部对齐,虽然设置alginBottom指向第一个he ...
- 重构第3天:方法提公(Pull Up Method)
理解:方法提公,或者说把方法提到基类中. 详解:如果大于一个继承类都要用到同一个方法,那么我们就可以把这个方法提出来放到基类中.这样不仅减少代码量,而且提高了代码的重用性. 看重构前的代码: usin ...
- Razor 在WebApp 框架的运用
前面有两章介绍了WebApp框架<WebApp MVC,“不一样”的轻量级互联网应用程序开发框架>和<WebApp MVC 框架的开发细节归纳>,其中视图引擎是用的Nveloc ...
- zk框架window之间传值操作
.zul中向Action传递参数: <listcell> <button label="修改" onClick="@command('edit',id= ...
- Core Animation 学习
core animation 是在UIKit层之下的一个图形库,用于在iOS 和 OS X 实现动画. Core Animation管理App内容 core animation不是一个完整的绘图系统, ...