字符串移动构造函数如何工作?

时间:2015-02-08 09:26:41

标签: c++ string memory dynamic move

我正在读一本关于c ++的书,试图学习这门语言。 有一个例子,它创建了一个类似矢量的类,只适用于名为stringV的字符串。该类定义了一个名为reallocate的函数,它应该分配新的动态内存,并在旧内存满了的情况下将其字符串移动到新内存中。

void stringV::reallocate(){
    size_t newcap = size() ? size() * 2 : 1;
    auto newalloc = alloc.allocate(newcap); 
    auto mem = newalloc;
    auto elem = element; // element pointes to the first string object in the memory segment
    for (size_t i = 0; i < size(); i++){
        alloc.construct(newalloc, std::move(*elem));
        newalloc++;
        elem++;
    }
    free(); //destroys and deallocates the dynamic memory held by this object
    element = mem;
    first_free = newalloc; // one past the last element
    cap = element + newcap; // last part of the possibly unconstructed memory

}

这个函数根据书中使用字符串类的移动构造函数,通过交换字符串对象之间的指针来窃取传递给它的对象的状态(我假设它是指向第一个元素的指针,类似于内置的在数组中)而不是分别复制每个字符。 例如,假设我们有一个名为stringV的{​​{1}}对象,它为3个字符串分配了足够的动态内存。我们首先分配字符串foo"one""two"。现在,当我们尝试推送第四个字符串"three"时,此容器必须通过调用"four"来重新分配内存。但是,字符串对象不是一个接一个地在相邻位置构建它们的字符(类似到内置数组的实现)。当我们使用move构造函数时,只窃取指向字符串中第一个char的指针。所以这并不意味着字符串元素(字符)reallocate"one""two"仍然存在于同一个旧的,现在已满的内存段中。并且新分配的内存只需要保存指向这些元素和任何新的后续字符串"three"等的指针。被推入我们的"four"对象?考虑到我们的字符串(字符数组)不再位于相邻位置,这对效率(至少可以说)有影响吗?

1 个答案:

答案 0 :(得分:1)

"one""two"之类的文字确实存储在相邻的内存中,但字符串在创建到缓冲区时会复制它们(文字是只读的)。无法保证字符串分配缓冲区的位置;字符串甚至不会自己分配缓冲区,而是使用分配器。

String的移动构造函数只是将缓冲区的所有权从旧字符串传递给新字符串,它不会更改内存中缓冲区的位置,因此在reallocate之后,所有缓冲区都将是在他们之前的相同地址。