Effective C++ Item 33 Avoid hiding inherited names

class Base {
private:
    int x;
public:
    virtual void mf1() = 0;
    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() = 0;
    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();
        ...
    }
};

 

posted @ 2014-03-01 12:44  SangS  阅读(145)  评论(0编辑  收藏  举报