[Effective C++ --033]避免遮掩继承而来的名称

这一章一直在想怎么写,因为比较基础,很容易理解,就按照需要来写吧。

假设我们有这样一个类:

 1 class Base {
 2 private:
 3     int x;
 4 public:
 5     virtual void mf1() = 0;
 6     virtual void mf2();
 7     void mf3();
 8     
 9 };
10 
11 class Derived : public Base {
12 public:
13     virtual void mf1();
14     void mf4();
15 };

如果mf4()的实现代码为:

1 void Derived::mf4(){
2     mf2();
3 }

在查找mf2()函数的过程中,先找mf4的函数作用域,在查找Derived类作用域,再查找Base类。

然后更改:

 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 class Derived : public Base { 
12 public: 
13     virtual void mf1(); 
14     void mf3(); 
15     void mf4(); 
16 };

然后调用:

1 Derived d; 
2 int x; 
3 d.mf1(); 
4 d.mf1(x);    //错误,Derived::mf1遮掩了Base::mf1 
5 d.mf2(); 
6 d.mf3(); 
7 d.mf3(x);    //错误,Derived::mf3遮掩了Base::mf3

我们可以使用using声明式达成目标:

 1 class Derived : public Base { 
 2 public:
 3 
 4 //base class内的public名称在publicly derived class内也应该是public。 
 5     using Base::mf1;    // 让base class内为mf1和mf3的所有东西 
 6     using Base::mf3;    //在Derived class作用域内都可见(并且public) 
 7     virtual void mf1(); 
 8     void mf3(); 
 9     void mf4(); 
10 };
11 
12 Derived d; 
13 int x; 
14 d.mf1(); 
15 d.mf1(x);//现在没问题了,调用Base::mf1 
16 d.mf2(); 
17 d.mf3(); 
18 d.mf3(x);//现在没问题了,调用Base::mf3

或者:

1 class Derived : private Base { 
2 public: 
3     virtual void mf1()//转交函数 
4     { 
5         Base::mf1();//暗自转成inline (条款30)
6     }
7 
8 9 };

◆总结

1.derived class内的名称会遮掩base class内的名称。在public继承下从来没有人希望如此。

2.为了让被遮掩的名称重见天日,可以使用using声明式或转交函数。

原文地址:https://www.cnblogs.com/hustcser/p/4262176.html