c++ - 具有互斥数据成员的对象的设计替代方案

标签 c++ design-patterns c++14

很难在标题中总结问题;所以请允许我澄清一下这里的情况。

我正在设计一个代表 BER TLV structure 的类.在本规范中,TLV 的“数据”部分可以包含数据的原始字节或其他嵌套的 TLV。为了支持这两种形式,我使用了相同的结构,但有两个 vector (实际上只有一个 vector 包含某些内容,具体取决于我们在解析 TLV 数据时发现的内容):

class BerTlv
{
public:

    void Parse(std::vector<std::uint8_t> const& bytes_to_parse);

    // Assume relevant accessors are provided

private:

    // Will be m_data or m_nestedTlvs, but never both
    std::vector<std::uint8_t> m_data;
    std::vector<BerTlv> m_nestedTlvs;
};

从外部来看,在这个对象被完全构建之后(所有的 TLV 数据被解析),用户将需要检测他们正在处理的数据类型。基本上,他们必须检查 m_data.empty(),如果是,则使用 m_nestedTlvs。我对这种方法不是很满意;闻起来好像缺少更好的设计。

我想到了某种形式的 union ,尽管我认为真正的 union 在这里不合适,因为 vector 数据是堆分配的。于是想到了std::variant:

std::vector<std::variant<BerTlv, std::uint8_t>> m_data;

但是,我担心这会对 std::uint8_t 情况产生负面影响,因为它实际上只是字节数据。它现在也将变得不连续。该变体仅对嵌套的 TLV 案例有利,而且获益不大。

接下来我考虑在这里使用访问者模式,但我无法完全想象界面的外观或这将如何提高两种情况下的可用性(原始数据与嵌套 TLV)。访问者是正确的解决方案吗?

到目前为止,我的想法都不对,所以我希望就此问题的更好设计方法提供反馈。这里的一般问题是数据成员有时未被使用或相互排斥。这也是我在其他情况下遇到的一个问题,所以如果有一个通用的设计方法来解决这样的问题就太好了。

请注意,我可以访问 C++14 及以下功能。

最佳答案

Basically, they'd have to check m_data.empty(), and if so, use m_nestedTlvs.

如果想法是一个对象要么有一个字节数组,要么有一个其他对象数组,那么这就是您应该使用的变体:variant<vector<std::uint8_t>, vector<BerTlv>> . vectorvariant s 与您指定的用例不匹配。

关于c++ - 具有互斥数据成员的对象的设计替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41349511/

相关文章:

ios - 在 Coordinator 模式中重用 View Controller

java - 模式 : Create and translate between data objects and wire formats

c++ - Qt - 向对话框添加超链接

c++ - 为什么 sizeof(std::variant) 与具有相同成员的结构的大小相同?

c++ - 解释 c/c++ 赋值期间逗号的异常使用

c# - 设计模式 : Which one to choose?

c++ - std::allocator 释放部分内存

c++ - 使用 vector 的 vector 的多个数组

c++ - 如何从一个函数锁定 shared_mutex 并从另一个函数解锁它?

android - C++通用多平台获取mac地址的解决方案