【问题标题】:Vector push_back calls object destructor向量 push_back 调用对象析构函数
【发布时间】:2019-07-04 04:57:34
【问题描述】:

类似的问题已经在这里被问过很多次了,但是按照答案并没有解决我的问题。

假设我有:

1)两个类(ACLass 和 BClass)

2)AClass 有一个构造函数和一个析构函数

3)BClass 有一个 std::vector 成员,用于存储 AClass 的对象

4) 该向量中的元素数量事先未知

5) 每当调用 BClass 方法 generateObject() 时,向量都会随着新 AClass 对象的创建而扩展。这是通过调用 std::vector.push_back() 来完成的。

class AClass {
    AClass()  { //Constructor }
    ~AClass() { //Destructor }
};

Class BClass {
    std::vector<AClass> object;

    void generateObject() {
        object.push_back(AClass());
    }
};

现在,在上面的示例中,generateObject() 只会工作几次。一旦向量变得太小而无法容纳所有对象,它就会执行各种内部操作以保留更多内存以进行扩展。问题是在此过程中调用了一些(如果不是全部)AClass 析构函数。

由于元素的数量是未知的,因此不能使用reserve() 为向量保留更多空间。使用 emplace_back() 也没有解决我的问题。

那么我该怎么做呢?有没有办法防止调用析构函数?在这种情况下使用 std::vector 是个好主意吗?

【问题讨论】:

  • std::list 适合吗?
  • “问题是在此过程中调用了一些(如果不是全部)AClass 析构函数。” 嗯,是的。为什么这是个问题?您还期望向量如何重新定位其元素?
  • @IgorTandetnik 是的,这可能是向量的工作方式,但它仍然在我的实现中引起问题。主题是如何更改实现,或者要实现什么来解决这个问题。
  • @thb std::list 不是很慢吗?是否可以像使用数组和向量一样使用 operator[] 访问 std::list 元素?
  • 嗯,具体来说,它在您的实施中造成了哪些问题?展示一个实际演示所述问题的示例。在向量重新分配上运行析构函数是正常的和预期的,通常不会被认为是有害的。如果它适合您,那么您的情况一定有什么不寻常之处 - 请解释它是什么。

标签: c++ vector destructor


【解决方案1】:

std::vector 扩展其存储空间时,它会将当前对象复制或移动到新的存储空间中。旧对象被丢弃,这本质上涉及对旧对象调用析构函数。

如果不希望销毁旧对象,std::dequestd::vector 具有或多或少相同的操作,但开销稍大一些,但无需重新分配存储空间。

如果内存使用不是问题,std::list 永远不会移动其存储的对象,但列表中的每个元素也有一对指针,一个指向列表中的前一个元素,一个指向下一个元素.

【讨论】:

  • 我一定会尝试的。感谢您的提示。
  • A std::deque 不重新分配存储空间?其实我并不知道,这些年来一直在deque的错误概念下运作。不过,现在我查看了 C++17 标准。 26.3.8.4.1 解释说,“在双端队列两端的插入会使双端队列的所有迭代器无效,但对双端队列元素引用的有效性没有影响。”此外,Cppreference.com 概述了实现此效果的数据结构。迷人。谢谢。
  • @Chriss555888 如果您发现 Pete Becker 的这个答案很有用,您可能会支持并且可能接受它。这就是感谢皮特的方式。请参阅左侧的橙色箭头和绿色复选控件。
  • @LightnessRacesinOrbit,是的,你是对的。我的程序中使用的类确实有问题。构造函数不会初始化析构函数破坏的所有内容。代码的另一部分是通过外部调用 init() 方法来初始化的。出于这个原因,每当向量进行大小调整(调用该对象的析构函数和构造函数)时,不会调用 init() 方法,因此该对象无法正常工作。正如您所说,使用 std::deque 只会掩盖问题。
  • @Chriss555888 -- 正如我所暗示的,std::deque 引入了std::vector 不存在的时间和空间开销。更重要的是,有一个不能正常工作的课程迟早会咬你一口。 “我的车的刹车不是很好,这没关系,因为我开得不够快,不会惹上麻烦。”直到你这样做。修复它。
猜你喜欢
  • 2019-03-22
  • 2018-02-21
  • 2014-03-14
  • 2021-02-03
  • 2013-02-23
  • 1970-01-01
  • 2015-08-11
  • 1970-01-01
  • 2020-08-18
相关资源
最近更新 更多