[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声明式或转交函数。