【问题标题】:Why does a move constructed object preserves the capacity of an empty private vector, while a copy constructed object does not?为什么移动构造的对象保留了空私有向量的容量,而复制构造的对象却没有?
【发布时间】:2019-06-14 12:51:03
【问题描述】:

代码

#include <iostream>
#include <vector>

class Dummy {
public:
    Dummy(int size=5) {array.reserve(size);};
    size_t capacity(){return array.capacity();};
private:
    std::vector<unsigned long long> array;
};

int main(int argc, char* argv[]){
    Dummy test1(10);
    Dummy test2(10);
    std::cout << "Initial capacity test1: " << test1.capacity() << std::endl;
    std::cout << "Initial capacity test2: " << test2.capacity() << std::endl;
    Dummy foo(test1);
    std::cout << "After copy capacity: " << foo.capacity() << std::endl;
    Dummy bar(std::move(test2));
    std::cout << "After move capacity: " << bar.capacity() << std::endl;
}

以上是使用 g++ 7.4.0 构建的,并返回以下内容:

初始容量测试1:10

初始容量测试2:10

复制后容量:0

移动后容量:10

问题

为什么移动构造的对象保留了空私有向量的容量,而复制构造的对象却没有?

【问题讨论】:

  • 移动一个std::vector“窃取”原始的内部内存缓冲区,所以它不会改变大小也就不足为奇了。
  • 这个例子不需要Dummy类——你可以用普通的vectors做同样的事情并观察它。移动的全部意义在于避免在“旧”对象不再需要资源的情况下重新创建资源(复制操作必须这样做)。
  • @molbdnilo 我不认为这个论点真的成立,因为复制构造可以用同样的方式来描述,但是 确实 改变了容量。容量不被视为vector 的“价值”的一部分 - 它不是显着属性

标签: c++


【解决方案1】:

因为复制就是复制。

当您复制矢量时,它会复制它拥有元素。不是你为未来元素计划的空白空间。虽然移动尽可能快,但结果它盲目地移动一切。就我个人而言,我不会计划我的代码。您应该依靠 move 移动保留空间,也不应该依靠 move 留下一个空容器。

【讨论】:

  • Because copy is copy. 好吧,如果它会复制所有内容(向量的值及其属性/元信息),那么它还需要确保容量相同。但是标准没有要求容量在复制后保持不变,也没有禁止,所以一个副本可以保持容量,但不是必须的。
  • 没有必要。这是一个更哲学的问题。向量的容量属性是值,还是变量的更多属性,即持有该值?在第一种情况下,它应该被复制,因为您希望新值与旧值相同。在第二种情况下,它不应该被复制,因为新值保存在不同的变量中。据我所知,标准并没有说明什么。
猜你喜欢
  • 2013-03-21
  • 1970-01-01
  • 2013-11-18
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 2015-05-29
相关资源
最近更新 更多