为什么一个物体在推到向量上时会被破坏

Why does an object get destroyed when pushing it to a vector?

本文关键字:向量 一个 为什么      更新时间:2023-10-16

我想知道为什么我推回到向量中的元素在这种情况下会调用其析构函数:

#include <iostream>
#include <vector>
class Foo
{
public:
    Foo(int a)
     : m_a(a)
    {
        std::cout << "Foo ctor() " << m_a << std::endl;
    }
    ~Foo()
    {
        std::cout << "Foo dtor() " << m_a << std::endl;
    }
private:
    int m_a;
};
class FooStorage
{
public:
    static void createFoo(int a)
    {
        m_foos.push_back(Foo(a));
    }
    static std::vector<Foo> m_foos;
};
std::vector<Foo> FooStorage::m_foos;
int main()
{
    std::cout << "Before: " << FooStorage::m_foos.size() << std::endl;
    FooStorage::createFoo(53);
    std::cout << "After: " << FooStorage::m_foos.size() << std::endl;
    return 0;
}

这会打印出以下内容:

Before: 0
Foo ctor() 53
Foo dtor() 53
After: 1
Foo dtor() 53

我想知道:

  • 什么会被删除?(位于"Before"answers"After"区域之间)
  • 为什么它会被删除
  • 向量中的结果是什么

您正在此处创建一个临时对象:

m_foos.push_back(Foo(a));
//               ^^^^^^

当完整表达式结束时,该对象的析构函数将被调用,但它将被push_back()复制(或移动)到向量中。

为了防止创建临时,可以使用emplace_back():就地构建

m_foos.emplace_back(a);
m_foos.push_back(Foo(a));

这将导致两个构造函数调用(,但这完全取决于它可以优化的编译器)。

Foo(a)

是一个临时的,它将被构造(一个构造函数调用),然后复制到向量(复制构造函数调用)。像往常一样,临时词一直存在,直到它们被使用的表达结束。因此,当push_back结束时,它将为这个临时调用析构函数(这就是为什么您看到对析构函数的调用)。