简体   繁体   English

如何在C ++中处理对象的混合集合

[英]How to handle mixed collections of objects in C++

I'm working on a C++ hierarchical tree-based class design, with two object types, A and B. 我正在研究基于C ++分层树的类设计,具有两个对象类型A和B。

Type A objects can have any number of children, of type either A or B, but they must be stored in a single sequential order. 类型A对象可以具有任意数量的类型为A或B的子代,但是它们必须以单个顺序存储。 Type B objects may not have any children. B型对象可能没有任何子代。

My question is regarding the best OO practices for handling collections of mixed types in C++. 我的问题是关于在C ++中处理混合类型集合的最佳OO实践。

One solution I can see would be to create a Base class, which from which both classes A and B are derived, and for A to hold a vector<Base*> children . 我可以看到的一种解决方案是创建一个基类,从该基类派生出A和B类,并让A容纳vector<Base*> children This seems like a good solution except for down the line there is more likely to be some dynamic casting to determine child type, which I've been told can be a symptom of poor code design. 这似乎是一个很好的解决方案,除了可以进行动态转换来确定子类型之外,我被告知这可能是代码设计不佳的征兆。

Another option would be for class A to hold a separate list of A and B children, along with a value to represent that child's position in the combined children list. 另一种选择是让A类持有A和B子代的单独列表,以及代表该子代在组合子代列表中的位置的值。 This seems like a more problematic solution as when items are inserted, removed or rearranged, the position values must be manually maintained. 这似乎是一个更有问题的解决方案,因为在插入,移除或重新排列项目时,必须手动维护位置值。

A third option would be to roll the functionality of classes A and B into one class and have a flag to note how to interpret the object. 第三种选择是将类A和B的功能滚动到一个类中,并有一个标记来说明如何解释该对象。

Are these my only options for this problem? 这些是我解决此问题的唯一选择吗? Am I missing some more elegant solution, or approaching it from the wrong direction? 我是否错过了一些更优雅的解决方案,或者是从错误的方向着手? I've seen that Boost has some options for heterogenous collections but using Boost isn't an option in this project unfortunately. 我已经看到Boost可以为异构集合提供一些选项,但是不幸的是,在这个项目中,使用Boost并不是一个选项。

EDIT: I'll try to describe the real case with some more details 编辑:我将尝试用一些更多的细节来描述真实的情况

Type A objects define collections. Type A对象定义集合。 They hold string paths or patterns, to define a set of objects (from a user created pool). 它们包含字符串路径或模式,以定义一组对象(来自用户创建的池)。 Children collections define further subets. 子级集合定义其他子集。

Type B objects are overrides. B类对象是替代对象。 They describe operations to be applied to the set of objects defined by parent A objects. 它们描述了要应用于父A对象定义的对象集的操作。

The order of the collections and collections determines the order in which the overrides are applied. 集合和集合的顺序确定应用替代的顺序。

The point where I was finding I needed to downcast was at an evaluation stage, where I was iterating through the tree to collate and apply the overrides - I needed to know how to treat each item in the tree and whether to look for location or override data. 我发现需要下调的点是在评估阶段,在树中进行迭代以整理和应用覆盖-我需要知道如何对待树中的每个项目以及是否要查找位置或覆盖数据。 From the comments I've received it seems I should able to accomplish what I need with real OO design, so I'll have another go before I can equivocally say otherwise. 从我收到的评论看来,我应该可以用真正的OO设计完成我需要的工作,因此在我可以明确地说另外的事情之前,我还要再做一次。

With C++17, you might utilize std::variant 在C ++ 17中,您可以利用std::variant

struct B {
// ...
};

struct A {
std::vector<std::variant<A, B> > children;
// ...
};

None of your proposed solutions have anything to do with OO or polymorphism or any such buzzword. 您提出的解决方案均与OO或多态性或任何此类流行语无关。 (Not that there's any inherent problem with that). (这并不意味着存在任何固有的问题)。

The OO solution would be to rely exclusively on virtual functions in Base to perform work specific to each particular derived class. OO解决方案将完全依赖Base 虚拟功能来执行特定于每个特定派生类的工作。 Nothing more and nothing less. 一无所有,一无所有。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM