在C ++中进行n次继承后停止从基类继承

时间:2019-01-07 04:42:44

标签: c++ inheritance

我有一个问题,我只需要继承一次基类。之后,我想阻止任何人继承此类。有人可以向我解释如何实现这一目标。而且,如果基类被继承的次数是n次(例如1 ..10),那么这样做的通用方法是什么。

我知道在基类中使用朋友类可以在某种程度上解决我的问题。但是我觉得这很笨拙。此外,我还读过有关Restrict inheritance to desired number of classes at compile-time的文章。我无法完全理解答案。

有人可以向我建议更好的方法来限制c ++编译时的继承。

3 个答案:

答案 0 :(得分:1)

  

当前,基类由内部团队继承一次。现在,此类可供第三方使用。但是我不希望他们继承这个基类。这就是问题陈述

问题在于C ++没有提供任何直接限制继承方式的方法。

指向实现惯用语的指针可能仍然可以帮助您解决问题:

class PublicToUser final
{
    class PrivateToUser;
    std::unique_ptr<PrivateToUser> implementation;
public:
    // ***
};

现在它将是实际继承的私有内部类,但是可以完全隐藏起来,即。 e。您根本不需要向用户公开该基类-不可见的内容将不会被继承...

答案 1 :(得分:0)

  

我有一个问题,我只需要继承一次基类。之后,我想阻止任何人继承此类。

从C ++ 11开始,您可以简单地使用final来防止类被进一步子类化:

class BaseClass { };

class DoNotInheritClass final : public BaseClass { };

为限制单个基类的子类数量,显然没有C ++内置功能。您需要通过添加一些静态变量自己来跟踪子类。这是现有的答案:Counting instances of individual derived classes

答案 2 :(得分:0)

如果您不能使用其他答案中的PIMPL解决方案,则以下一些想法可能会有所帮助。它们基于CRTP或基于构造函数标记:

#include <type_traits>

struct A;

template<typename T>
struct Base final {

};

// Specialise Base for A to be non-final
template<>
struct Base<A> {};

struct A : Base<A> {};

第一个摘要的想法是建立一个基于final的CRTP,并为类A添加一个非最终的专业化名称。显然,这允许用户(或您自己)在需要时定义更多允许的派生,但可以防止意外继承。

template<char...>
struct password {};

struct Base2 {

    Base2() = delete;

    template<char... pwd>
    Base2(password<pwd...> ) {
        using expected_pwd = password<'t','o','p','s','e','c','r','e','t'>;
        static_assert(std::is_same_v<password<pwd...>, expected_pwd>);
    }
};

struct A2 : Base2 {

    A2() : Base2(password<'t','o','p','s','e','c','r','e','t'>{}) {}
};

struct A3 : Base2 {

    // No way to construct Base2 without correct password :)
    A3() : Base2(password<'b', 'a', 'm', 'm'>{}) {}
};

第二个片段(比实际代码更多的是个玩笑...)背后的想法是用Base2结构代替password类的默认构造函数。在实现中,您检查提供给构造函数的密码。在派生类的实现中,您只需使用正确的密码调用Base2构造函数即可。当然,您的用户可以从基类派生,但是由于密码完全隐藏在实现中,因此无法构造派生对象:)

int main(){

    auto a = A{};
    auto a2 = A2{};
    auto a3 = A3{};  // fails
    return 0;
}
相关问题