Effective C++ 条款33 :避免遮掩继承而来的名称

Effective C++ 条款33 :避免遮掩继承而来的名称

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

class Derived : public Base
{
public:
    virtual void mf1();
    void mf4();
};

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

查找规则 :在上述代码中,编译器看到了mf2(),需要知道它指的是什么东西。编译器的做法是查找各个作用域,看看有没有名为mf2的声明式。
首先查找local作用域,也就是函数mf4()内部。如果没有,查找外围作用域,也就是class Derived范围。如果还是没有找到,
继续向外移动,在class Base中查找,在这里,编译器查到了一个函数Base::mf2(),停止查找。假如Base::mf2()不存在,
查找继续,不出意外应该是进入命名空间的范围内查找,如果还没有,最后进入全局空间,和系统函数一个等级的作用域范围内去查找。

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

void main()
{
    Derived d;
    int x;
    d.mf1();            //Derived::mf1
    d.mf1(x);           //error!!  Derived::mf1 掩盖了 Base::mf1
    d.mf2();            //Base::mf2
    d.mf3();            //Derived::mf3
    d.mf3(x);           //error  Derived::mf3 掩盖了 Base::mf3
}

上面的查找规则对virtual或者non-virtual都适用。编译器建立这套行为的理由是为了防止在程序库或者框架内建立新的Derived class
附带地从疏远的base classes继承重载函数。这句话比较拗口,简单来说就是如果派生类public继承了基类,但是又不重写那些virtual function,
包括基类的重载的需函数。那么就违反了派生类和基类的is-a关系。当然有时候我们并不想继承基类的所有函数。怎么使用方法来解决这个问题?

//使用using来解决
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:
    using Base::mf1;
    using Base::mf3;
    virtual void mf1();
    void mf3();
    void mf4();
};

void main()
{
    Derived d;
    int x;
    d.mf1();            //Derived::mf1
    d.mf1(x);           //没问题 Base::mf1
    d.mf2();            //Base::mf2
    d.mf3();            //Derived::mf3
    d.mf3(x);           //没问题Base::mf3
}

上面使用using引入基类的函数,可以避免派生类中覆盖基类的一些函数。从实际上来说,尽量避免这种情况最佳。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值