【发布时间】:2021-11-09 10:09:25
【问题描述】:
我正在尝试为几个存储数据的类找到最佳设计。 据我所知,我可以用继承做一些事情:
struct Data
{
int a;
int b;
int c;
};
struct DerivedData : public Data
{
int d;
};
struct AnotherDerivedData : public Data
{
int e;
};
或组合:
struct ComposedData
{
Data data;
int d;
};
struct AnotherComposedData
{
Data data;
int e;
};
我倾向于继承,因为 Data 和 DerivedData 之间存在关系。但是我想知道这是否是一个好的设计,因为绝对没有要继承的功能?
此外,数据不应该单独使用,所以我想知道是否可以将其抽象化,是否值得?我已经读过要做到这一点,你应该创建一个纯虚拟析构函数,或者最好是一个受保护的构造函数:
struct Data
{
int a;
int b;
int c;
protected:
Data() = default;
};
但我不喜欢这里的是,它在原本简单的结构中引入了一些复杂性。它甚至不是 POD(如果我正确理解 POD 的话)。
关于最佳实施的任何建议?还有其他方法吗?
编辑:我意识到我对主要困扰我的事情还不够清楚: DerivedData 和 Data 之间存在“is-a”关系。但由于某种原因,我觉得继承有点“过度”,因为没有要覆盖的函数(甚至根本没有函数)。但也许这是我的一个误解,继承在这里是完全合适的?
【问题讨论】:
-
“数据不应单独使用”:这是否意味着您的 Composed/DerivedData 的“消费者”也不应该能够处理 a、b 或 c?
-
上下文太少,不能基于意见。
Data、DerivedData和AnotherDerivedData是什么? pod-ness 的相关性是什么? (一旦你有了一个基类,它就不是 pod,那么如果Data是 pod,为什么还要麻烦呢?) -
是的,在现代 C++ 中,普通的旧数据通常并不重要——有时其他事情也很重要,比如 const 可初始化,或默认可构造(或可复制构造、可移动……取决于上下文)
-
Data代表 Engine 和DerivedDataCar,还是DataCar 和DerivedDataPorshe?这真的取决于你在建模什么以及你想从中得到什么。 -
@MarcusMüller 我的意思是客户通常应该使用 Composed/DerivedData 而不仅仅是数据。数据包含一些必需但不充分的基本信息(至少对于我想做的事情,但我想也许我应该允许客户在他们愿意的情况下只使用数据)。客户端应该能够处理 a、b 或 c。
标签: c++