class Base {
private:
int x;
public:
virtual void mf1() = ;
virtual void mf2();
void mf3();
...
}; class Derived: public Base {
public:
virtual void mf1();
void mf4();
...
};

上面代码构成了一个 namespace

在 derived class 内的 mf4 代码实现为

void Derived::mf4() {
...
mf2();
...
}

编译器看到 mf2 后现在 mf4 的作用空间查找, 然后到 Derived 的作用空间查找, 最后在 Base 中找到.

2. 我们再考虑前一个例子, 这次让我们重载 mf1 和 mf3

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();
...
};

从名称查找观点来看, Base::mf1 Base::mf3 不再被 Derived 继承, 因为 Base class 内的函数被遮蔽了

Derived d;
int x;
..
d.mf1();
d.mf1(x); // 错误! Derived::mf1 遮蔽了 Base::mf1
d.mf2();
d.mf3();
d.mf3(x); // 错误! Derived::mf3 遮蔽了 Base::mf3

为了达成本来需要的目的, 我们只需在 Derived class 内添加两行代码

using Base::mf1;
using Base::mf3;

现在, 上面发生错误的代码都不会报错了, 一切按照既定的轨道在前进!

3. 但有时候, 你并不像继承 Base class 的所有函数, 这时可以理解的. 这在 public inheritance 中不可发生(见 item 32) 但 private inheritance 却是有可能的, 那么部分继承的一个很好的解决方案是 转交函数

class Derived: private Base {
public:
virtual void mf1() { // 转交函数
Base::mf1();
...
}
};

Effective C++ Item 33 Avoid hiding inherited names的更多相关文章

  1. 条款33:避免遮掩继承而来的名称(Avoiding hiding inherited names)

    NOTE: 1.derived classes 内的名称会遮掩base classes内的名称.在public继承下从来没有人希望如此. 2.为了让被遮掩的名称再见天日,可使用using 声明方式或转 ...

  2. effective C++ Item 33 避免隐藏继承而来的名字

    1. 普通作用域中的隐藏 名字实际上和继承没有关系.有关系的是作用域.我们都知道像下面的代码: int x; // global variable void someFunc() { double x ...

  3. 读书笔记 effective C++ Item 33 避免隐藏继承而来的名字

    1. 普通作用域中的隐藏 名字实际上和继承没有关系.有关系的是作用域.我们都知道像下面的代码: int x; // global variable void someFunc() { double x ...

  4. Effective C++ Item 33 避免遮掩继承过来的名称

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie ? 不懂 c++为什么derived classes 内的名称要遮掩 base classe ...

  5. Effective JavaScript Item 33 让构造函数不再依赖newkeyword

    本系列作为EffectiveJavaScript的读书笔记. 在将function当做构造函数使用时,须要确保该函数是通过newkeyword进行调用的. function User(name, pa ...

  6. 读书笔记 effective c++ Item 43 了解如何访问模板化基类中的名字

    1. 问题的引入——派生类不会发现模板基类中的名字 假设我们需要写一个应用,使用它可以为不同的公司发送消息.消息可以以加密或者明文(未加密)的方式被发送.如果在编译阶段我们有足够的信息来确定哪个信息会 ...

  7. Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数

    作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...

  8. Effective C++ Item 36 绝不又一次定义继承而来的 non-virtual 函数

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:绝对不要又一次定义继承而来的 non-virtual 函数 --> Item 7 ...

  9. 读书笔记 effective c++ Item 36 永远不要重新定义继承而来的非虚函数

    1. 为什么不要重新定义继承而来的非虚函数——实际论证 假设我告诉你一个类D public继承类B,在类B中定义了一个public成员函数mf.Mf的参数和返回类型并不重要,所以假设它们都是void. ...

随机推荐

  1. rm: cannot remove `dir': Device or resource busy解决办法

    使用df查看系统发现: [ops@bs038 cm-5.4.0]$ df -hFilesystem Size Used Avail Use% Mounted on/dev/sda3 1.1T 200G ...

  2. 【linux】Shell脚本启动程序

    Linux 下后台脚本启动Jar程序 Nohup后台输出运行日志 cd /home/zeze/jar/WeiboPost java -jar WeiboAutoPost.jar ../configur ...

  3. mysql show full processlist

    processlist命令的输出结果显示了有哪些线程在运行,可以帮助识别出有问题的查询语句,两种方式使用这个命令. 1. 进入mysql/bin目录下输入mysqladmin -u -p -h127. ...

  4. c++重载前置++和--

    C语言中,前置和后置++,--都不能作为左值,而在c++中,前置的++和--可以作为左值,从下面的重载运算符中也可以看出,它们返回的是引用,我不知道为什么这里和c语言中不同,但c++类似的提升还有三目 ...

  5. Entity Framework4.3安装以及错误(基础连接已经关闭:未能为SSL/TLS……)问题解决!

    Entity Framework以下简称EF 安装EF4.3的步骤是首先安装VS扩展 NuGet,然后再使用NuGet安装EF程序包 安装完NuGet就可以安装EF了,有两种方式可以安装EF: 1.使 ...

  6. kubernetes service访问原理

    k8s集群中有三类IP: 1:宿主机的物理网卡IP,比如192.168.255.* 2:cni创建的网卡的IP,比如172.16.*.* 3:虚拟的IP(即ClusterIP ,无法ping通,通过代 ...

  7. wso2as安装

    1.系统环境 Ubuntu12.04    192.168.0.97    root/password找管理员 Ubuntu12.04    192.168.0.99    root/password ...

  8. centsos7修改主机名 [root@st152 ~]# cat /etc/hostname

    CentOS7修改服务器主机名方法CentOS7下修改主机名第一种:hostname 主机名01.hostname 主机名称 <pre name="code" class=& ...

  9. java-TokenProcessor令牌校验工具类

    TokenProcessor令牌校验工具类 public class TokenProcessor { private long privious;// 上次生成表单标识号得时间值 private s ...

  10. FFmpeg API变化

    可以查看doc目录下的APIchanges和根目录下的Changelog 去掉了ffserver程序   'avcodec_register_all' is deprecated 还有av_regis ...