/*此处一定要声明,否则在NonDerivableHelper类中将NonDerivable定义为友元类时,会认为是Private中的某个类*/
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
{
...
};
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,编译器将保证这种情况不会出现。
xiterator(xi):
类的继承体系中若有类成为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不能被继承的目的。