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

    • 此例中混合了纯虚函数、虚函数、非虚函数等,只是为了强调隐藏的是继承而来的名字,至于名字代表的是什么并不重要,即使enum、nested class、typedef也不例外。

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 class Base
     6 {
     7 public:
     8     virtual void mf1() = 0;
     9     virtual void mf1(int);
    10     virtual void mf2();
    11     void mf3();
    12     void mf3(double);
    13 
    14 private:
    15     int x;
    16 };
    17 
    18 class Derived : public Base
    19 {
    20 public:
    21     virtual void mf1();
    22     void mf3();
    23     void mf4();
    24 };
    25 int main()
    26 {
    27     Derived d;
    28     int x;
    29     d.mf1();    // 正确:调用Derived::mf1
    30     d.mf1(x);   // 错误:因为Derived::mf1隐藏了Base::mf1
    31     d.mf2();    // 正确:调用Base::mf2
    32     d.mf3();    // 正确:调用Derived::mf3
    33     d.mf3(x);   // 错误:因为Derived::mf3隐藏了Base::mf3
    34 
    35     return 0;
    36 }

    说明:Base类中的任何同名函数都会被Derived类中同名函数隐藏掉,不论函数是否为虚函数,这些机制的是为了防止从基类中继承重载函数。实际上如果你使用public继承而又不继承基类中的重载函数,那就违反了is-a关系。

     

    • 如果确实想使用基类Base中同名的函数,那么就需要使用using Base::名字

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 class Base
     6 {
     7 public:
     8     virtual void mf1() = 0;
     9     virtual void mf1(int);
    10     virtual void mf2();
    11     void mf3();
    12     void mf3(double);
    13 
    14 private:
    15     int x;
    16 };
    17 
    18 class Derived : public Base
    19 {
    20 public:
    21     using Base::mf1;    // 让Base类中名为mf1和mf3的所有东西在
    22     using Base::mf3;    // 派生类Derived中可见
    23     virtual void mf1();
    24     void mf3();
    25     void mf4();
    26 };
    27 
    28 int main()
    29 {
    30     Derived d;
    31     int x;
    32     d.mf1();    // 正确:调用Derived::mf1
    33     d.mf1(x);   // 正确:调用Base::mf1(int)
    34     d.mf2();    // 正确:调用Base::mf2
    35     d.mf3();    // 正确:调用Derived::mf3
    36     d.mf3(x);   // 正确:调用Base::mf3(double)
    37 
    38     return 0;
    39 }

    • 在public继承下,不想继承Base中的所有函数是不可能的。考虑private继承下的一个例子:Derived以private方式继承Base,其想唯一继承的是mf1的无参版本,如果使用using,那么重载版本也会被继承。以下描述了一个简单的转交函数(forwarding function):

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 class Base
     6 {
     7 public:
     8     virtual void mf1() = 0;
     9     virtual void mf1(int);
    10     virtual void mf2();
    11     void mf3();
    12     void mf3(double);
    13 
    14 private:
    15     int x;
    16 };
    17 
    18 class Derived : private Base
    19 {
    20 public:
    21     virtual void mf1()  // forwarding function
    22     {
    23         Base::mf1();
    24     }
    25     void mf3();
    26     void mf4();
    27 };
    28 
    29 int main()
    30 {
    31     Derived d;
    32     int x;
    33     d.mf1();    // 正确:调用Derived::mf1
    34 
    35     return 0;
    36 }

    总结:Derived中的名称会隐藏Base中的名称,不论是什么类型,而使用using声明或者转交函数可以解决这个问题。

  • 相关阅读:
    js 日期
    二级导航 css
    ajax 输出json数据
    三列板块 css效果
    随机18个数 js
    js 表单非空验证
    ajax案例,调用XML文件
    :hover 鼠标悬浮时(基本导航)
    下载html5-boilerplate(通过npm)
    鼠标滚动,导航置顶.纯css3的position: sticky;
  • 原文地址:https://www.cnblogs.com/benxintuzi/p/4525376.html
Copyright © 2011-2022 走看看