C++11提供的final关键字可以禁止类继承,例如
class A final {};
而在此之前,可通过将构造函数声明为private的方式(不继承,单例模式),例如
class A
{
public:static A *getInstance() { ...省略实现 }
private:A() {}static A *s_instance;
};
或者将派生类(类B、类C等)声明为类A的友元(继承,友元方式),例如
template <typename T>
class A
{friend T;A() {}
};class B : public A<B> {};
class C : public A<C> {};
class D : public B;int main()
{B b;C c;D d;return 0;
}
我们发现,类D借助类B作为跳板,脱离了类A当初设定友元类的限定,为了强制直接派生自类A的类(例如类B、类C)不可再次派生(例如类D),采用虚继承的方式,实现如下:
class B : public virtual A<B> {};
class C : public virtual A<C> {};
class D : public B;
int main()
{B b;C c;D d; // 编译报错(模板特性,不定义该变量时编译可以通过)return 0;
}

原因:由于类B采用虚继承的方式来继承类A,类D的构造函数将会优先使用类A的构造函数,而类D并非类A的友元,所以编译失败(若类B普通继承类A时,由于类D的构造函数并不会直接使用类A的构造函数,而是借助类B去使用类A的构造函数,变能够因为类B是类A的友元而编译成功)。