我正在构建一个C ++类A
,它需要包含一堆指向其他对象B
的指针。
为了使课程尽可能通用,我在这个课程中使用std::vector<B*>
。这样就可以在B
中保存任意数量的不同A
(对可以存在的数量没有限制)。
现在这可能有点过分,因为大多数时候,我将使用A
类型的对象,它只在向量中包含2或4 B*
个。
由于将要进行大量的迭代计算,涉及类A
的对象,我想知道使用B
的向量是否涉及很多开销当只需要两个B
时。
如果存在少于3个B
,我是否应该重载该类以使用另一个容器?</ p>
让事情更清晰: A
是多极, B
是磁线圈,构成多极
答案 0 :(得分:12)
过早优化。让它先工作。如果您对应用程序进行概要分析并发现需要更高的效率(内存或性能),那么然后就可以更改它。否则,这可能是浪费时间。
答案 1 :(得分:2)
如果你需要一个永远不会改变其大小的B*
数组,你将不需要std::vector
的动态缩小和增长能力。
所以,可能不是出于效率的原因,但出于直觉的原因,你可以考虑使用固定长度的数组:
struct A {
enum { ndims = 2 };
B* b[ndims];
};
或std::array
(如果有):
struct A {
std::array<B*, 2> b;
};
另请参阅有关该主题的this answer。
答案 2 :(得分:2)
我现在会使用一个向量,但键入一个名称,而不是拼写std::vector
直接用于它的位置:
typedef std::vector vec_type;
class A {
vec_type<B*> whatever;
};
然后,当/如果它成为问题时,您可以更改该typedef名称以引用针对少量包含对象优化的类似矢量的类(例如,执行类似于小字符串优化的常见问题许多std::string
}的实现。
另一种可能性(尽管我不太喜欢它)是继续直接使用名称“vector”,但使用using
声明来指定要使用的vector
:< / p>
class A {
using std::vector;
vector<B*> whatever;
};
在这种情况下,当/在必要时,您将替换vector
放入命名空间,并将using
声明更改为指向该声明:
class A {
using my_optimized_version::vector;
// the rest of the code remains unchanged:
vector<B*> whatever;
};
就如何实现优化类而言,典型的方法是这样的:
template <class T>
class pseudo_vector {
T small_data[5];
T *data;
size_t size;
size_t allocated;
public:
// ...
};
然后,如果您要存储5个或更少的项目,则将它们放在small_data
中。当/如果向量包含的项目多于该固定限制时,则在堆上分配空间,并使用data
指向它。
根据你想要优化的内容,你可能想要使用一个抽象基类,有两个后代,一个用于小向量,另一个用于大向量,带有类似pimpl的类来包装它们和让任何一个行为像你可以直接使用的东西。
另一种可能对某些情况有用的可能性是继续使用std::vector
,但提供自定义的Allocator对象,以便在获取存储空间时使用。谷歌搜索“小对象分配器”应该出现一些已经写过的候选人。根据具体情况,您可能希望直接使用其中一种,或者您可能希望将它们作为灵感来编写自己的。
答案 3 :(得分:1)
就开销而言,向量非常精简。我相信这里有人可以提供更详细的信息。但如果你遇到性能问题,他们就不会来自矢量。
此外,我肯定会避免使用不同容器的策略,具体取决于有多少项目。那只是在乞求灾难,并不会给你任何回报。