防止头文件之外的子类

时间:2014-08-22 14:10:20

标签: c++ inheritance c++11

我在.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类中方法的定义。

我正在考虑将继承范围限制在头文件中(类似于静态变量)。任何建议或想法将不胜感激。

1 个答案:

答案 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;
}

http://ideone.com/NUWad0

另请注意:基类的复制/移动构造函数可能也应该是私有的。我没有添加代码来专注于主要提案,但您也应该考虑它。


关于朋友构造函数进行编辑。

首先:在编译器看到定义之前,你不能引用不完整类型的成员(它可以作为一次性传递,并且可能涉及一些重载决策)。这意味着以下工作无效:

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();
};

...

因此,在您的特定情况下,除非您想要修改设计中的某些内容,否则最好使用朋友类访问。