序言
目前掌握的如下三种方法。
一、private (此方法不妥,自己都没法在类外构造了)
二、final (C++11)
三、使用友元和模板
方法讲解
一、private
此方法就是在某个类中将此类构造函数声明为private即可。
class TestNoInheritance
{
private:
TestNoInheritance()
{
qDebug() << __FUNCTION__;
}
~TestNoInheritance();
};
class TestNoInheritanceChild :public TestNoInheritance
{
public:
TestNoInheritanceChild()
{
qDebug() << __FUNCTION__;
}
~TestNoInheritanceChild();
};
会出现编译错误。
但这样只能通过公有静态成员函数访问。
二、 final
此final在C++11中引用
class TestNoInheritance final //子类不能继承
{
public:
TestNoInheritance()
{
}
~TestNoInheritance();
virtual void fool() final; //此方法告诉子类虚函数不能被继承,重现实现
};
class TestNoInheritanceChild :public TestNoInheritance
{
public:
TestNoInheritanceChild()
{
qDebug() << __FUNCTION__;
}
~TestNoInheritanceChild();
};
会提示父类被标记为final,不能被继承。
三、使用友元和模板
将A的构造函数和析构函数都声明为private的,但是将B作为A的友元类,这样B就可以访问A的构造函数和析构函数了,此时B能正常构造;
为了使B的子类C不能被正常构造,可以让C直接调用A的构造函数,那么将B设置成虚拟继承自A;
因为友元关系是不能被继承的,所以C调用A的构造函数时会报错
和第一种错误的解法相比,主要使将A的构造函数和析构函数声明是private的了,并且将B声明是A的友元类,其实这种解法和A的思路是一样的,就是让B能调用A的构造函数,让B的子类不能调用A的构造函数,只是第一种错误的解法没有满足这个要求。
更进一步,可以将它写成模板:
#include <iostream>
using namespace std;
template<class T>
class A
{
friend T;//注意这里不需要class关键字
//将构造函数和7构函数都声明是私有的
private :
A()
{
}
~A()
{
}
};
class B:public virtual A<B> //这里一定需要使用虚继承,只有使用虚继承,它的子类才会直接调用A类的构造函数,这样才会报错,如果是普通继承,那么通过B类调用A类的构造函数时时不会报错的
{
};
class C:public B
{
};
int main()
{
B b;
cout<<"success"<<endl;
// C c;
return 0;
}