在非POD数据类型的std :: vector中,对象向量和对象(智能)指针向量之间是否存在差异?我的意思是编译器对这些数据结构的实现存在差异。
E.g:
class Test {
std::string s;
Test *other;
};
std::vector<Test> vt;
std::vector<Test*> vpt;
vt和vpt之间可能没有性能差异吗?
换句话说:当我定义vector<Test>
时,编译器会在内部创建vector<Test*>
吗?
答案 0 :(得分:2)
通常,无论向量中存储的类型是什么,都可以复制其实例。这意味着如果要存储std :: string,将复制std :: string的实例。
例如,当您将Type推入向量时,Type实例将被复制到向量内部的实例中。复制指针会很便宜,但正如Konrad Rudolph在评论中指出的那样,这不应该是你唯一考虑的事情。
对于像Test
这样的简单对象,复制速度会非常快,无关紧要。
此外,使用C ++ 11,移动可以避免在没有必要的情况下创建额外的副本。
简而言之:指针将被更快地复制,但复制并不是唯一重要的事情。当问题成为问题时(或者情况需要它),我会首先担心可维护的逻辑代码和性能。
关于内部指针向量的问题,不,向量被实现为在必要时定期调整大小的数组。你可以在网上找到GNU的libc ++矢量实现。
答案在低于C ++级别时变得更加复杂。指针当然必须参与,因为整个程序不适合寄存器。虽然我不太了解那个低级别的内容,但我还不太了解。
答案 1 :(得分:2)
换句话说:当我定义一个向量时,编译器内部会创建一个向量吗?
不,C ++标准不允许这样做。以下代码是合法的C ++:
vector<Test> vt;
Test t1; t1.s = "1"; t1.other = NULL;
Test t2; t2.s = "1"; t2.other = NULL;
vt.push_back(t1);
vt.push_back(t2);
Test* pt = &vt[0];
pt++;
Test q = *pt; // q now equal to Test(2)
换句话说,向量“衰减”到数组(像C数组一样访问它是合法的),因此编译器有效地必须在内部将元素存储为数组,并且可能不仅存储指针。
但请注意,只要矢量未重新分配(通常仅在大小超出容量时才会发生),数组指针才有效。