我有一个问题,我只需要继承一次基类。之后,我想阻止任何人继承此类。有人可以向我解释如何实现这一目标。而且,如果基类被继承的次数是n次(例如1 ..10),那么这样做的通用方法是什么。
我知道在基类中使用朋友类可以在某种程度上解决我的问题。但是我觉得这很笨拙。此外,我还读过有关Restrict inheritance to desired number of classes at compile-time的文章。我无法完全理解答案。
有人可以向我建议更好的方法来限制c ++编译时的继承。
答案 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;
}