[Effective C++ --033]避免遮掩继承而来的名称
这一章一直在想怎么写,因为比较基础,很容易理解,就按照需要来写吧。
假设我们有这样一个类:
class Base {
private:
int x;
public:
virtual void mf1() = ;
virtual void mf2();
void mf3();
};
class Derived : public Base {
public:
virtual void mf1();
void mf4();
};
如果mf4()的实现代码为:
void Derived::mf4(){
mf2();
}
在查找mf2()函数的过程中,先找mf4的函数作用域,在查找Derived类作用域,再查找Base类。
然后更改:
class Base {
private:
int x;
public:
virtual void mf1() = ;
virtual void mf1(int);
virtual void mf2();
void mf3();
void mf3(double);
};
class Derived : public Base {
public:
virtual void mf1();
void mf3();
void mf4();
};
然后调用:
Derived d;
int x;
d.mf1();
d.mf1(x); //错误,Derived::mf1遮掩了Base::mf1
d.mf2();
d.mf3();
d.mf3(x); //错误,Derived::mf3遮掩了Base::mf3
我们可以使用using声明式达成目标:
class Derived : public Base {
public:
//base class内的public名称在publicly derived class内也应该是public。
using Base::mf1; // 让base class内为mf1和mf3的所有东西
using Base::mf3; //在Derived class作用域内都可见(并且public)
virtual void mf1();
void mf3();
void mf4();
};
Derived d;
int x;
d.mf1();
d.mf1(x);//现在没问题了,调用Base::mf1
d.mf2();
d.mf3();
d.mf3(x);//现在没问题了,调用Base::mf3
或者:
class Derived : private Base {
public:
virtual void mf1()//转交函数
{
Base::mf1();//暗自转成inline (条款30)
}
…
};
◆总结
1.derived class内的名称会遮掩base class内的名称。在public继承下从来没有人希望如此。
2.为了让被遮掩的名称重见天日,可以使用using声明式或转交函数。
[Effective C++ --033]避免遮掩继承而来的名称的更多相关文章
- Effective C++ 33 避免遮掩继承而来的名称
首先介绍一个原则LSP(Liskov Substitution Principle),如果Class D以Public方式继承Class B,则所有B对象可以派上用场的任何地方,D对象一样可以派上用场 ...
- Effective C++ -----条款33:避免遮掩继承而来的名称
derived classes内的名称会遮掩base classes内的名称.在public继承下从来没有人希望如此. 为了让被遮掩的名称再见天日,可使用using声明式或转交函数(forwardin ...
- Effective C++:条款33:避免遮掩继承而来的名称
(一) 以下这段代码: int x; void someFunc() { double x; //local variable std::cin>>x; //read a new valu ...
- 读书笔记_Effective_C++_条款三十三:避免遮掩继承而来的名称
名称的遮掩可以分成变量的遮掩与函数的遮掩两类,本质都是名字的查找方式导致的,当编译器要去查找一个名字时,它一旦找到一个相符的名字,就不会再往下去找了,因此遮掩本质上是优先查找哪个名字的问题. 而查找是 ...
- 条款33:避免遮掩继承而来的名称(Avoiding hiding inherited names)
NOTE: 1.derived classes 内的名称会遮掩base classes内的名称.在public继承下从来没有人希望如此. 2.为了让被遮掩的名称再见天日,可使用using 声明方式或转 ...
- [EffectiveC++]item33:避免遮掩继承而来的名称。
先看看: ZT C++ 重载.覆盖和隐藏的区别 http://www.cnblogs.com/jeanschen/p/3405987.html 隐藏是指派生类的函数屏蔽了与其同名的基类函数,规则如下: ...
- Effective C++ Item 33 避免遮掩继承过来的名称
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie ? 不懂 c++为什么derived classes 内的名称要遮掩 base classe ...
- Effective JavaScript Item 40 避免继承标准类型
本系列作为Effective JavaScript的读书笔记. ECMAScript标准库不大.可是提供了一些重要的类型如Array,Function和Date.在一些场合下.你或许会考虑继承当中的某 ...
- Effective C++ 34 区分接口继承和实现继承
public继承从根本上讲,有两部分:接口继承和实现继承.两者之前的区别很像函数声明与函数定义. 具体设计中,会呈现三种形式:derived class只继承成员函数的接口(纯虚函数):derived ...
随机推荐
- SQL你必须知道的-增删改查与约束
SQL你必须知道的-增删改查与约束 -- 插入数据 --Insert 语句可以省略表名后的列名,但是不推荐 insert into Class values ('' 高一一班 '', ...
- 使用 gradle 编译多版本 android 应用
最近要做一个 android 产品的变种版本,需要编出不同版本,每个版本有不同的包名.图标等等,和一些特有的逻辑. 很久之前做过类似的工作,当时没有 gradle, 用的方法是把公共代码抽成一个 li ...
- CentsOS7 网络自动启动
虚拟机中安装完成CentOS7后,网络总是需要手工启动才可使用,设置为自动连接的方式如下: cd /etc/sysconfig/network-scripts/ls #找到类似的文件:ifcfg-et ...
- Programming Impala Applications
Programming Impala Applications The core development language with Impala is SQL. You can also use J ...
- 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇08:弹幕系统》本系列完结
8.弹幕系统 弹幕系统概述: 弹幕系统的设计体现了射击游戏的基本要素,玩家要在敌人放出的大量子弹(弹幕)的细小空隙间闪避,能在玩家闪躲弹幕的时候给玩家带来快感,接近满屏的子弹,增加了对玩家的视觉冲击力 ...
- Linux虚拟机创建后如何进行登录(Windows Azure)
Linux虚拟机创建后如何进行登录 若要管理虚拟机的设置以及在其上运行的应用程序,可以使用安全外壳 (SSH) 客户端.为此,您必须在计算机上安装要用于访问虚拟机的 SSH 客户端.您可以选择很多 S ...
- 10个专属于移动app开发者的最佳移动JavaScript框架
1.Titanium Mobile JavaScript Frameworks Titanium Mobile JavaScript框架是移动应用开发者(Android & iOS)首选的最优 ...
- POJ 1847 Tram (最短路)
Tram 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/N Description Tram network in Zagreb ...
- 发布ASP.NET网站时的设置
在ASP.NET网站开发完成之后,一般都要进行发布,然后再使用. 点击“目标位置”后的按钮可以选择将网站发布到的位置,有“本地.本机IIS.FTP站点.远程网站站点”四个选项. 另外,发布网站时还有四 ...
- CABasicAnimation精讲
前言 本教程写了这个效果图的demo,同时总结CABasicAnimation的使用方法. 看完gif动画完,看到了什么?平移.旋转.缩放.闪烁.路径动画. 实现平移动画 实现平移动画,我们可以通过t ...