Effective-cpp-#33

Avoiding hiding iherited names

这里的关键是区分清楚重载与重写

继承一个基类时,如果其下的public函数不带virtual,而派生类又重写了一个同名的函数,那么派生类就会把基类版本的该函数给掩盖住了,也就是无法再通过派生类去调用基类版本的函数了

解决方法

有两种解决方法:

第一种是使用using声明式:

1
2
3
4
5
6
7
8
9
10
11
class Base{};

class Derived: public Base{
public:
//保证Base class内名为mf1和mf3的所有东西在Derived域内可见
using Base::mf1;
using Base::mf3;
virtual void mf1();
void mf3();
void mf4();
};

通过这种手段,继承机制没有问题,在派生类找不到的函数(版本),会继续到基类作用域内寻找。

第二个方法就是使用forwarding function,特别是你如果想要隐藏到基类不同参数的函数中某一个,用例子说话:

1
2
3
4
5
6
7
8
9
10
11
12
class Base{
public:
virtual void mf1() = 0;
virtual void mf1(int);
};

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

这样就隐藏掉带参数的mf1()了

建议

  • Derived class内的名称会隐藏掉base class内的函数。在public继承体系下,我们不希望发生这样的事情;
  • 为了重新获取被掩盖的基类函数,可以使用using声明式或者forwarding functions