1

我有两个(不相关的)课程。第一个是“点”:

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 类继承自 Point 和 Vertex,并且没有任何成员

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

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

感谢您的见解!

4

2 回答 2

1

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

因为设计是妥协的,所以我要从我的角度指出主要的不同之处。

相关/不相关的顶点类型

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

要编写的代码量

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

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

于 2012-06-20T00:29:26.343 回答
0

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

原因:

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

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

因此,回答您的问题:您似乎没有足够的理由使用多重继承。使用组合。

于 2012-06-20T00:09:21.310 回答