public继承细分为两种,一方面它继承了基类的接口,另一方面它同样继承了基类的实现。对于纯虚函数来说,它表达的意思是只继承接口,而实现需要你自己去做。非纯虚函数使得派生类同时继承接口和缺省实现。但这常常带来问题,尤其是对基类不怎么熟悉的用户。classBase{public: virtual void fun1();};classDerived : publicBase{public: //未覆写fun1函数};//使用了缺省的fun1Derived d;d.fun1();
因为对基类的不熟悉,派生类并没有覆写非纯虚函数fun1。但是下一位用户并不知道这一回事,使用了缺省实现的fun1,造成了意想不到的效果。问题在于必须让派生类的实现者默认只继承接口,缺省实现则要去主动继承。class Base{public: virtualvoidfun1() = 0;protected: voidrealfun1();};class Derived : public Base{public: //必须覆写fun1函数 virtualvoidfun1() { realfun1(); }};
通过上面代码的修改,fun1变成了一个纯虚函数,意味着派生类实现者默认只继承了接口,缺省实现要由其主动调用realfun1函数继承。还有一种方法类似上面,但是避免了realfun1函数,却带来了缺省实现保护级别也是public的问题:class Base{public: virtualvoidfun1()= 0;};voidBase::fun1(){ //缺省实现 }class Derived : public Base{public: //必须覆写fun1函数 virtualvoidfun1() { Base::fun1(); }};
不再使用realfun1函数,直接在纯虚函数fun1的定义中缺省实现,但缺省实现保护级别也是public。这个也很简单,意味着用户继承接口和一份强制性实现。