假设我有一个完全虚拟/抽象类INode(接口),它的所有方法都是纯虚拟的。随后,我想已经从它继承一个CNode将实现这些方法的类。我也想创建一个子接口,例如INodeSpatial,也是完全虚拟的,它会继承所有父级的虚拟方法+添加一些自己的虚拟方法。稍后我想从它继承CNodeSpatial所有这些方法将被实现的地方。嗯,等等..
但这里有以下内容:
CNode继承自的类INode将实现虚方法INode- 再次,全班
CNodeSpatial希望只来自 virtualINodeSpatial,而不是来自CNode,这意味着CNodeSpatial我将不得不描述在CNode - 有一个想法不这样做 - 继承
CNodeSpatial和INodeSpatial继承(已经描述CNode了所有虚拟方法的实现)。INode然后我将不得不只描述那些在INodeSpatial
但问题来了:
这有多好和正确?事实证明,该类CNodeSpatial是两次继承自INode(因为它INode是 andCNode和 and的父级INodeSpatial)。那么有可能吗?这会导致未来出现问题吗?这种方法在多大程度上符合“良好做法”?
例子:
接口
class INode
{
public:
virtual void methodA() = 0;
virtual void methodB() = 0;
virtual ~INode() = default;
};
class INodeSpatial : public INode
{
public:
virtual void methodC(int foo) = 0;
virtual void methodD(int foo) = 0;
~INodeSpatial() override = default;
};
“真实”课程:
class CNode : public INode
{
public:
void methodA() override
{
//TODO: Implementation of INode methods in CNode
}
void methodB() override
{
//TODO: Implementation of INode methods in CNode
}
};
class CNodeSpatial : public INodeSpatial
{
public:
void methodA() override
{
//TODO: Implementation of INode methods in CNodeSpatial (already done in CNode)
}
void methodB() override
{
//TODO: Implementation of INode methods in CNodeSpatial (already done in CNode)
}
void methodC([[maybe_unused]] int foo) override
{
//TODO: Implementation of INodeSpatial methods
}
void methodD([[maybe_unused]] int foo) override
{
//TODO: Implementation of INodeSpatial methods
}
};
如您所见,该类CNodeSpatial必须复制已经在 中描述的实现CNode,因为继承完全来自虚拟接口。但是如果 AND 继承自СNode,问题似乎就消失了:
class CNodeSpatial : public INodeSpatial, public CNode
{
public:
void methodC([[maybe_unused]] int foo) override
{
//TODO: Implementation of INodeSpatial methods
}
void methodD([[maybe_unused]] int foo) override
{
//TODO: Implementation of INodeSpatial methods
}
};
但最后,事实证明,该类实际上是从 INode 继承了 2 次,这让我感到困惑。这可以?他们这样做吗?以后会不会出问题?

你可以这样做:
由于基类是抽象的,派生类也将保持抽象,因为它没有定义纯虚方法。但是它添加了新的,不是纯的,虚拟方法,而只是受保护的方法,以便派生类可以覆盖或不覆盖。在实践
INodeSpatial中,它是构建派生类的典型宿主类:现在
CNode在其公共接口中只有方法来自INode好吧,这一个也定义了方法 from
INodeSpatial,以及与层次结构相对应的类型名称。我想指出,我完全同意有问题的第一条评论(来自 avp)。尽量保持简单。例如,如果不需要创建层次树(这种形式只出现两个类),以便通过引用基类来编写基本代码,那么您应该考虑摆脱所有多余的东西。 .
你的感官没有让你失望。
您的示例与
class CNodeSpatial : public INodeSpatial, public CNode您的想法不符。使用这种方法的类
CNodeSpatial是抽象的 - 尝试创建一个实例,你会看到。解决方案 -
CNode应该INodeSpatial从INode虚拟继承。