C++ View第一期: /*此处一定要声明,否则在NonDerivableHelper类中将NonDerivable定义为友元类时,会认为是Private中的某个类*/ class NonDerivable; namespace Private{ class NonDerivableHelper { NonDerivableHelper() {} friend class NonDerivable; }; } #ifdef NDEBUG #define FINAL_CLASS #else #define FINAL_CLASS : private virtual Private::NonDerivableHelper #endif class NonDerivable FINAL_CLASS { ... }; 初次看到这个例子时,对其中
的private virtual继承方法不是很理解。而这种继承方式恰恰是该例子的精华部分。 virtual在这里的意思是虚拟继承。它主要是为了解决多重继承时基类数据在子类中出现两次以上,从而引起访问二义的问题。例 class A{ public: int i; }; class B:public A {}; class C:public A {}; class D:public B, public C {}//here D has 2 copy of A::i, one comes from B and another comes from C 在上述情况下,对C::i的访问是二义的,但如果B, C都虚拟继承A,编译器将保证这种情况不会出现。
类的继承体系中若有类成为virtual base class(即与其子类之间均通过virtual方式继承的话),那么其构造函数的调用是由最终具体类(本例WantToDerive)来做的。而WantToDerive是经由NonDerivable private继承NonDerivableHelper,所以无法调用NonDerivableHelper的构造函数。 若将virtual去掉,则NonDerivableHelper构造函数的调用是由NonDerivable来做的,而NonDerivable是NonDerivableHelper的友元,所以可以访问相应的构造函数。
从以上解释我们可以看到,该例子主要使用了C++中virtual继承方式和友元不能被继承的两个特性。通过将NonDerivableHelper 的构造函数定义为private,同时将子类NonDerivable声明为该类的友元类。因此NonDerivable可以实例化。但由于NonDerivable是通过virtual方式继承的NonDerivableHelper ,因此其子类的构造函数调用NonDerivableHelper 的构造函数时,是直接调用,而不是通过NonDerivable其调用,故出现“不能调用私有的NonDerivableHelper::NonDerivableHelper()”错误,从而实现了NonDerivable不能被继承的目的。
|