这种情况下允许:如何禁止C++派生类从基地获得,而是从另一个派生类
class GrandParent {};
class Parent : public GrandParent {};
class Child : public Parent {}; /// Ok
class Child : public GrandParent {}; /// Is it possible to force a compilation error?
这种情况下允许:如何禁止C++派生类从基地获得,而是从另一个派生类
class GrandParent {};
class Parent : public GrandParent {};
class Child : public Parent {}; /// Ok
class Child : public GrandParent {}; /// Is it possible to force a compilation error?
充分利用GrandParent
构造私人和Parent
朋友。
class GrandParent
{
friend class Parent;
private:
GrandParent() {}
// ...
};
或者,您可以通过使析构函数私人权衡的GrandParents
多态性破坏:
class GrandParent
{
friend class Parent;
private:
virtual ~GrandParent() {}
};
// Invalid Destruction:
GrandParent* p = new Parent;
...
delete p;
另一种方法来解决这个问题的方法是使用“模板神奇”。如果你试图改变父类祖父母
#include <type_traits>
class Child : public Parent
{
};
static_assert(std::is_base_of<Parent, Child>::value, "Child must derive Parent");
,编译器给你错误
是的,我同意你的看法。 – LmTinyToon
考虑到这一点,它可以扩展到更可靠的事情。如果OP的方法使用'T *'的参数和SFINAE检查,T'从'GrandParent'派生,*它们可以包含'T'从'Parent'派生的'static_assert',以拒绝任何派生自'Parent'。但这只是让我想到:OP想要完成什么?在这种情况下,更简单更安全的方法是首先将其限制为“Parent”,而不用担心其他'GrandParent'派生的类。 – hvd
我不明白你有点想过。 – LmTinyToon
如果它的唯一目的是作为'Parent'一个基类,: 你应该子类声明后添加以下代码为什么'GrandParent'存在? –
@PeteBecker对于“普通”继承可能没有理由,但对于技巧,当然(基于成员的成语,EBO,主要类的普通成员及其专业化......此列表可以继续,并继续)。对于现实生活中的例子,请考虑libstdC++的'std :: vector' – milleniumbug
@milleniumbug - 这个继承层次中没有任何东西表明它是用于“技巧”的。如果是这样,这个问题应该这样说,以获得更合适的答案。 –