这个多重继承的例子在C++中是否可以接受

Is this example of multiple inheritance acceptable in C++?

本文关键字:是否 C++ 多重继承      更新时间:2023-10-16

我有两个(不相关的)类。第一个是"点":

typedef std::complex<double> complex_number;
class Point
{
public:
    Point(const complex_number &affix);
    const complex_number & get_affix() const;
    void set_affix(const complex_number & new_affix);
    // etc
private:
    complex_number affix_;
};

(顺便说一句,很抱歉问这个不相关的问题,但是在哪里放置我的类型定义是正确的地方?在这里,我的 point.hpp 文件的顶部,"好做法"?

第二个是"Abstract_Vertex"(这是稍后抽象图的一部分):

typedef int vertex_label;
class Abstract_Vertex
{
public:
    Abstract_Vertex(const vertex_label &label);
    const vertex_label & get_label() const;
    const vertex_label & get_neighbor_label(const int &index) const;
    void set_label(const vertex_label &new_label);
    bool is_neighbor_label(const vertex_label &label) const;
    // etc
protected:
    vertex_label label_;
    std::vector<vertex_label> neighbor_labels_;
};

现在我想创建第三个类,"Plane_Vertex"(位于平面中某处的顶点)。我正在考虑两种方法:

  1. 多重继承:Plane_Vertex类从点和顶点继承,并且没有任何成员

  2. Plane_Vertex类仅继承自 Vertex,并具有私有Point point_成员。

当然,我可以很容易地避免多重继承,只选择选项2,但我是一个很好的认真C++学习者,我想知道在我的情况下什么是"好的做法"。

感谢您的见解!

可能有第三种选择。您可以像标准库一样执行,并将AbstractVertex设置为模板。然后,可以在模板中实现图形导航和通用功能,并让用户提供要作为模板参数存储在节点中的值。

因为设计是妥协的,所以我将从我的角度指出主要区别。

相关

/不相关顶点类型

在模板方法中,不同的实例化是完全不同的类型。这意味着Vertex<int>Vertex<Point>不相关。另一方面,在所有顶点之上的多态方法IntVertexPointVertex...是AbstractVertex对象:您可以将它们组合在容器中并连接它们,或者在可以使用 AbstractVertex 的代码中互换使用它们。无论这是任何一种方法的限制还是优势,这同样是一个设计决策。我更喜欢这些类型不相关,因为我觉得你不应该混合这些类型。

要编写的代码量

在模板方法中,

您实现模板,然后只是实例化,在多态方法中,您需要为要包含在图形中的每个可能元素提供一个新类

如果最后你决定采用多态方法(我不会),那么我会避免使用两种类型的多重继承,而更喜欢组合。一般来说,继承可能是面向对象语言最被滥用的特性,它可以用来解决很多问题,有时它似乎是最简单的解决方案,但事实并非如此。特别是,您的基类型似乎都不是为继承而设计的,没有派生类型可以重写的功能,没有虚函数。这些清楚地表明,你在构图就足够的情况下滥用继承权。

通常,除非您有充分的理由进行多重继承,否则请避免使用。

原因:

  1. 您可以避免钻石问题。
  2. 保持设计尽可能简单 - 在几个级别之后,多重继承确实很难遵循和维护。
  3. 当您不使用多重继承时,检查您的类是否满足良好设计的 SOLID 原则通常更容易。
  4. 组合和/或聚合通常提供良好或更好的方法。
  5. 测试您的课程更容易。

这些应该足以让你开始。乔恩·凯奇(Jon Cage)链接到的帖子中有更多的智慧。

因此,要回答您的问题:看起来您没有足够充分的理由来使用多重继承。使用构图。