C++ 阻止头文件之外的子类

C++ 阻止头文件之外的子类,c++,inheritance,c++11,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。我想阻止用户

我在.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进行子类化。我“本可以”使用关键字“final”作为类库,但这会阻止我在头文件中进行子类化。我需要在头文件中包含上面所有的类,因为用户需要在Base和DerivedX类中提供方法的定义


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

您可以将
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;
}
并且不能向前声明基类(您不知道为派生对象分配多少空间):


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

您可以将基本构造函数设置为私有,并使这两个类成为friend类。我真的不喜欢这种想法。基类没有继承自它们的派生类的概念或概念,那么为什么它们能够禁止派生类的存在呢+1关于亮度,如果我是你,我会改变设计中的一些东西。但这可能与问题无关,我感觉你试图用错误的方法来解决问题。
Derevied1
Derived2
如何从
Base
派生获益?如果从
Base
派生出其他类,会产生什么危害?@LightnessRacesinOrbit基类不需要有允许派生类的概念吗?e、 提供虚拟析构函数,或者如果基类派生自另一个类,则可能使用虚拟继承,以防稍后有人创建菱形…我也会这样做。不过需要注意的是,我会使用namespace std删除
,因为这是一种不好的做法,而且在这段代码中没有任何作用。@Rapptz我同意,这只是一个快速的代码片段,但最好避免这种情况。ThanksIt不会阻止对基底进行分类@omid这是正确的,我刚刚试过。我可以定义“类Derived3:public Base{};”。如果编译器已经/可能已经将其标记为错误,我会很高兴。但是,如果我尝试实例化Derived3,编译器会生成一个错误。我想这已经足够好了。基类的Copy/move构造函数也应该是私有的。
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();
};

...