在创建时指定内容首选项的C ++ Design结构

时间:2017-04-05 17:14:14

标签: c++ design-patterns

我想创建一个数据结构来捕获生产,销售和库存数据的时间序列。但是,对于所有情况,我们不需要跟踪所有数据。在构建/启动系列时指定要跟踪的确切数据(例如销售和库存但不生产)。

一种方法可能如下。

struct ProductionDataEntry { ... };
struct SalesDataEntry { ... };
struct InventoryDataEntry { ... };
// Each of the above struct could be arbitrarily large

struct DataEntryV1 {
  ProductionDataEntry pde_;
  SalesDataEntry      sde_;
  InventoryDataEntry  ide_;
};

typedef std::chrono::system_clock::time_point TimePoint;

struct TimeSeriesEntry {
  TimePoint timepoint_;
  DataEntry entry_;
};

std::deque<TimeSeriesEntry> time_series;

以上方法的缺点如下。在用例中,销售和库存数据是必需的,而不是生产,数据结构仍然会占用ProductionDataEntry的空间。

我正在寻找一种可以避免这种空间浪费的方法。

有两种选择:

  1. 为每种数据创建单独的时间序列,并仅填充必要的时间序列。但是,这会多次复制TimePoint数据,并通过将收集的数据分布在多个数据结构上来破坏数据的位置。

  2. DataEntry作为指针组织到各个数据条目,例如

    struct DataEntryV2 {
      ProductionDataEntry * pde_{nullptr};
      SalesDataEntry      * sde_{nullptr};
      InventoryDataEntry  * ide_{nullptr};
    };
    

    并仅构造必要的数据输入对象。但是,这会破坏内存并引入额外的分配和释放开销,如果可能的话我希望避免这种开销。

  3. 使用DataEntry组织std::optional,例如

    struct DataEntryV3 {
      std::optional<ProductionDataEntry> pde_;
      std::optional<SalesDataEntry>      sde_;
      std::optional<InventoryDataEntry>  ide_;
    };
    

    我认为每个条目类型需要一个额外的单词。它仍然会消耗不必要数据的空间。

  4. 我想知道,设计领域还有其他选择吗?

    (注意:DataEntry可能需要扩展才能包含新类型的数据,例如PreOrderData。)

2 个答案:

答案 0 :(得分:0)

  

为每种数据创建单独的时间序列并仅填充   那些必要的时间序列。但是,这会复制TimePoint   数据多次通过传播来破坏数据的位置   通过多种数据结构收集数据。

可以通过继承来实现这一点。例如:

struct DataEntryV1: public ProductionDataEntry, public SalesDataEntry {};

您仍然需要定义要使用的每种数据类型,但它不会“破坏数据的局部性”。作为奖励,请查看通过多态性获得的所有代码重用。

我将此作为一个简单的选项,您应该在决定执行此操作之前阅读this link有关多重继承的内容。

答案 1 :(得分:0)

如果您在编译时知道,可以使用模板:

template <typename ... Ts>
struct TimeSeriesEntry {
    TimePoint timepoint_;
    std::tuple<Ts...> entries_;
};

// No Production
std::deque<TimeSeriesEntry<SalesDataEntry, InventoryDataEntry>> time_series;