2012-04-29 133 views
6

如何做一个std::vector<std::string>初始化自身时,下面的代码调用std :: vector的拷贝构造函数是如何操作的?

std::vector<std::string> original; 
std::vector<std::string> newVector = original; 

这似乎好像拷贝构造函数将在std::vector<std::string> new期间newVector = original被调用,却怎么也带来了内部的std::stringorginal?他们是复制品还是新的std::stringnewVector[0]中的内存也与original[0]相同。

的原因,我问的是说我做了以下

#include <vector> 
#include <string> 
using namespace std; 

vector<string> globalVector; 

void Initialize() { 
    globalVector.push_back("One"); 
    globalVector.push_back("Two"); 
} 

void DoStuff() { 
    vector<string> t = globalVector; 
} 

int main(void) { 
    Initialize(); 
    DoStuff(); 
} 

t就会掉出来的DoStuff范围(在非优化的版本),但如果它t只是充满指针指向std::string“ s在globalVector,可能会调用析构函数并将std::string中使用的内存删除,这里用于填充globalVector[0]的垃圾std::stringDoStuff被调用后?

坚果壳,我基本上是问,当std::vector的拷贝构造函数被调用时,里面的元素是如何被复制的?

+4

很确定这只是一个例子,但在你的第一个代码块中,'std :: vector new = original;','new'不是合法的变量名。我相信你知道这是一个保留关键字。 – 2012-04-29 00:12:21

+0

@ChrisA .:你说得对,它只是测试代码 – chadb 2012-04-29 00:41:23

回答

12

std::vector和大多数其他标准库容器按值存储元素。元素在插入或复制容器时被复制。 std::string也保留其自己的数据副本,就您的使用而言。

+3

其中大部分==全部。 – 2012-04-29 00:10:15

+2

@BenjaminLindley:就货柜的使用者而言,你是对的。然而,正如你最可能知道的那样,Stroustrup提醒我们一些容器,比如'std :: string',可能会懒惰地复制数据,这意味着实际的复制操作可能不会在内部完成,直到其中一个字符串(原始或该副本)的使用方式要求完成。无论如何,我认为在这种情况下,回答者在技术上是正确的,尤其是在他以合格的方式说出他的用法。 – thb 2012-04-29 00:18:20

+2

@thb'std :: string'只是一个容器的排序,它仅限于“类字符类型”(即不能存储其他容器),并且在多线程流行的时候不推荐使用写时复制。 – Potatoswatter 2012-04-29 00:25:58