我在.h文件中定义了以下三个类:
class Base
{ // number of pure virtual functions };
class Derived1 : public Base
{ // number of pure virtual functions };
class Derived2 : public Base
{ // number of pure virtual functions };
我希望此头文件的用户只能继承Derived1或Derived2。我想阻止用户子类化Base。我“可以”为类Base使用关键字“final”,但这会阻止我在头文件中进行子类化。我需要在头文件中包含所有上述类,因为用户需要提供Base和DerivedX类中方法的定义。
我正在考虑将继承范围限制在头文件中(类似于静态变量)。任何建议或想法将不胜感激。
答案 0 :(得分:17)
你可以将Base
构造函数设为私有,并让这两个类成为朋友,例如
#include <iostream>
class Base
{
private:
Base() {}
friend class Derived1;
friend class Derived2;
};
class Derived1 : public Base
{
};
class Derived2 : public Base
{
};
int main() {
Derived1 obj;
Base obj2; // Error
return 0;
}
另请注意:基类的复制/移动构造函数可能也应该是私有的。我没有添加代码来专注于主要提案,但您也应该考虑它。
关于朋友构造函数进行编辑。
首先:在编译器看到定义之前,你不能引用不完整类型的成员(它可以作为一次性传递,并且可能涉及一些重载决策)。这意味着以下工作无效:
class Derived1;
class Derived2;
class Base
{
private:
Base() {}
friend Derived1::Derived1(); // Error - incomplete type 'Derived1' in nested name specifier
};
class Derived1 : public Base
{
public:
Derived1() {};
};
...
并且您无法转发声明基类(您不会知道为派生对象分配多少空间):
class Base;
class Derived1 : public Base // Error: base class has incomplete type
{
public:
Derived1() {};
};
class Base
{
private:
Base() {}
friend Derived1::Derived1();
};
...
因此,在您的特定情况下,除非您想要修改设计中的某些内容,否则最好使用朋友类访问。