zoukankan      html  css  js  c++  java
  • 条款33:避免遮掩继承而来的名称

    首先看下下面这个例子:

    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();
        ...
    };
    这个函数里面还有纯虚函数,虚函数以及非虚函数。
    如果这里derived class调用了一个mf2函数的话,那么那么会先在derived class的范围类线进行mf2的查找,再在base class中进行查找,最后才是全局作用域。
     
    那么如果是下面这个例子的话:
     1 class Base{
     2 private:
     3     int x;
     4 public:
     5     virtual void mf1() = 0;
     6     virtual void mf1(int);
     7     virtual void mf2();
     8     void mf3();
     9     void mf3(double);
    10     ...
    11 };
    12 class Derived : public Base{
    13 public:
    14     virtual void mf1();
    15     void mf3();
    16     void mf4();
    17     ...
    18 };    
    在这个例子中,基类中的所有的被声明为mf1,mf3的函数都会被覆盖掉(注意,不管参数列表是如何的,也不管基类中是virtual还是non-virtual函数)。
    如果这种情况下想要能够选取到基类作用域中的mf1以及mf3,使得继承机制能够起作用的话就应该使用using声明:
     1 class Base{
     2 private:
     3     int x;
     4 public:
     5     virtual void mf1() = 0;
     6     virtual void mf1(int);
     7     virtual void mf2();
     8     void mf3();
     9     void mf3(double);
    10     ...
    11 };
    12 class Derived : public Base{
    13 public:
    14     using Base::mf1;
    15     using Base::mf3;
    16     virtual void mf1();
    17     void mf3();
    18     void mf4();
    19     ...
    20 };    

    然而可能有时候不希望集成基类中的所有函数,这时候就应该注意了,应为public提供的is-a的关系,所以说如果一旦不希望继承基类中的所有的函数,那么可能public集成并不是真正我们希望用到的关系,正如一个矩形与一个正方形之间的关系一样。这种只想继承一部分函数的欲望在私有继承制之下是可以得到满足的,例如下面这样:(不过要用到一点技巧)

     1 public:
     2     virtual void mf1() = 0;
     3     virtual void mf1(int);
     4     ...
     5 };
     6 class Derived: private Base{
     7 public:
     8     virtual void mf1(){    //    注意这里只能使用这种形式进行函数的转接,使用类似前面的类似的using声明达不到相同的结果。
     9         Base::mf1();
    10     }//转交函数。
    11 };
    类似的,转交函数也同样用在不支持using声明的编译器上面。
     
    小结:
    1.derived class中的名称会遮掩bass class中的名称,这是使用public集成不希望看到的
    2.出现这种情况时,可以使用using声明护着转接函数来改善这种情况。
  • 相关阅读:
    第十八章所有者权益部分考点知识点
    会计基础模拟练习一(3)
    会计基础模拟练习一(2)
    会计基础模拟练习一(1)
    第三章 复式记账
    第二章 会计科目和账户 笔记
    【Flink系列一】Flink开启Checkpoint,以及从Checkpoint恢复
    【已解决】解决Gradle在使用代理的情况下访问中央仓库返回403 Forbidden的问题
    Surface Laptop 3三个月使用心得
    Spring跨系统转发HTTP请求的简易实现(支持下载文件二进制流)
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4889762.html
Copyright © 2011-2022 走看看