集装箱中的集装箱是一个糟糕的设计吗

Is container of containers a bad design?

本文关键字:集装箱 一个      更新时间:2023-10-16

我需要一个容器容器,比如:

class Widget {
  ...
};
...
std::vector<std::list<Widget> > widgets;

因为STL容器复制其中的对象,并且复制容器不是一种廉价的操作,我认为这种容器容器可能会导致非常糟糕的效率,从而导致糟糕的设计。我想知道我是否是对的。如果是,我应该使用容器中的容器指针还是其他什么?感谢

p.s

谢谢你们,现在我知道这是不是一个糟糕的设计取决于我如何使用它

因此,如果我知道(最多)有多少list会插入到vector中,然后使用vector::reserve来避免vector的重新分配,然后我只查询其中的对象,这可能是一个很好的设计。

另一方面,如果我需要不时地将list插入到vector中,这可能会导致非常糟糕的效率。

我说得对吗?

设计不错。你使用它的方式可能是糟糕的设计。如果您的代码需要频繁的深度复制,并且您实现了std::vector<std::list<Widget> *> widgets,但仍然需要深度复制,那么与您所做的没有太大区别。

例如,如果您非常频繁地查询向量中list的某个成员,这实际上可能是一个很好的设计,因为向量的紧凑性导致内存接近。

具有移动语义的支持C++11的现代编译器通常会移动数据,而不是复制数据。因此,我不会太担心矢量的重新定位或移动只要比复制更有意义,使用std::swap的旧编译器仍然可以执行"移动"。

我相信你的设计问题的答案主要取决于你的项目的特殊性,而我们看不到。您需要存储值(并管理小部件的寿命)还是只存储引用?

请注意,std::vector仅在复制矢量时复制元素。否则,当您只需要增加向量容量时,它会使用通常很便宜的元素移动构造函数。

没有,为什么会这样?

如果使用得当,它们不会成为瓶颈,就像一个"简单"的STL容器一样。

使用不当(设计明智),它们当然会照你说的做,而且效率极低。

对于您的特定问题,您可能希望将指针而不是对象存储为数据。