这个多重继承的例子在C++中是否可以接受
Is this example of multiple inheritance acceptable in C++?
我有两个(不相关的)类。第一个是"点":
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"(位于平面中某处的顶点)。我正在考虑两种方法:
多重继承:Plane_Vertex类从点和顶点继承,并且没有任何成员
Plane_Vertex类仅继承自 Vertex,并具有私有
Point point_
成员。
当然,我可以很容易地避免多重继承,只选择选项2,但我是一个很好的认真C++学习者,我想知道在我的情况下什么是"好的做法"。
感谢您的见解!
可能有第三种选择。您可以像标准库一样执行,并将AbstractVertex
设置为模板。然后,可以在模板中实现图形导航和通用功能,并让用户提供要作为模板参数存储在节点中的值。
因为设计是妥协的,所以我将从我的角度指出主要区别。
相关/不相关顶点类型
在模板方法中,不同的实例化是完全不同的类型。这意味着Vertex<int>
和Vertex<Point>
不相关。另一方面,在所有顶点之上的多态方法IntVertex
,PointVertex
...是AbstractVertex
对象:您可以将它们组合在容器中并连接它们,或者在可以使用 AbstractVertex
的代码中互换使用它们。无论这是任何一种方法的限制还是优势,这同样是一个设计决策。我更喜欢这些类型不相关,因为我觉得你不应该混合这些类型。
要编写的代码量
在模板方法中,您实现模板,然后只是实例化,在多态方法中,您需要为要包含在图形中的每个可能元素提供一个新类
如果最后你决定采用多态方法(我不会),那么我会避免使用两种类型的多重继承,而更喜欢组合。一般来说,继承可能是面向对象语言最被滥用的特性,它可以用来解决很多问题,有时它似乎是最简单的解决方案,但事实并非如此。特别是,您的基类型似乎都不是为继承而设计的,没有派生类型可以重写的功能,没有虚函数。这些清楚地表明,你在构图就足够的情况下滥用继承权。
通常,除非您有充分的理由进行多重继承,否则请避免使用。
原因:
- 您可以避免钻石问题。
- 保持设计尽可能简单 - 在几个级别之后,多重继承确实很难遵循和维护。
- 当您不使用多重继承时,检查您的类是否满足良好设计的 SOLID 原则通常更容易。
- 组合和/或聚合通常提供良好或更好的方法。
- 测试您的课程更容易。
这些应该足以让你开始。乔恩·凯奇(Jon Cage)链接到的帖子中有更多的智慧。
因此,要回答您的问题:看起来您没有足够充分的理由来使用多重继承。使用构图。
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- C/C++预处理器是否可以检测一些编译器选项
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话