条款33 Avoid hiding inherited names
避免遮掩继承而来的名称
如图,derived class的mf1和mf3函数会把base class中的mf1和mf3全部函数“替换掉”,也就是说,以下代码是不能通过编译的
Derived d;
int x;
d.mf1(x);
d.mf3(x);
因为derived class中的mf1和mf3函数没有可以接受一个int值的重载形式。如果需要base class中的重载形式,需要更改代码
这样执行上述代码就不会出问题了
但是上述情况是在使用public继承下的方式,如果是private继承下这么做可能是有意义的。using声明式在这里派不上用场,需要一个简单的转交函数(forwarding function)
条款34 Differentiate between inheritance of interface and inheritance of implementation
区分接口继承和实现继承
pure virtual函数只能继承函数接口,但是可以为pure virtual提供定义并且调用,只需要调用的时候写明作用域即可。
impure virtual 函数会提供一份实现代码,目的是让derived class继承其接口和默认实现。
当base class编写了一个impure virtual函数时,避免在derived class中不得不override某个virtual函数却忘记覆写时造成的问题,应该将其函数声明为pure virtual函数,然后再提供一个protected的non-virtual default函数,在不需要默认函数的derived class中就单独书写此函数,需要默认函数的derived class使用inline调用默认函数即可。
更好的设计方式是使用pure virtual函数的定义取代之前的protected non-virtual default函数。
声明 non-virtual 函数的目的是为了令 derived classes 继承函数的接口及一份强制性实现。