gpt4 book ai didi

c++ - emplace_back 调用移动构造函数和析构函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:34:31 26 4
gpt4 key购买 nike

我尝试将类 cBar 的两个实例放置到具有 emplace_back 函数的 vector 中。

根据reference调用 emplace_back 仅保留 vector 中的位置,然后“就地”创建新实例。

现在,我试着用它做实验:

#include <vector>
#include <iostream>
#include <memory>
#include <string>


class cBar
{
public:

cBar(const int index);
cBar(cBar&& other); //needed for emplace_back?
~cBar();

private:
cBar(const cBar& other) = delete;
cBar& operator=(const cBar& other) = delete;

public:
int mIndex;

};




cBar::cBar(const int index) : mIndex(index)
{
std::cout << "cBar being created ..." << std::endl;
}
cBar::cBar(cBar&& other) : mIndex(other.mIndex)
{
std::cout << "cBar being moved ..." << std::endl;
}
cBar::~cBar()
{
std::cout << "cBar being destroyed ..." << std::endl;
}

int main()
{
std::vector<cBar> mBars;

std::cout << "Begin to create 2 cBar instance, I am expecting 2 \"cBar being created ...\" messages here" << std::endl;
mBars.emplace_back(0);//this supposed to call only cBar(const int index) constructor, and nothing more
mBars.emplace_back(1);//this works as expected, only one constructor call

//destroy all
std::cout << "Destroy the 2 isntances (this works, I see the two expected \"cBar being destroyed ...\" messages here" << std::endl;
mBars.clear();

std::cin.get();
return 0;
}

输出:

Begin to create 2 cBar instance, I am expecting 2 "cBar being created ..." messages here
cBar being created ...
cBar being moved ...
cBar being destroyed ...
cBar being created ...
Destroy the 2 isntances (this works, I see the two expected "cBar being destroyed ..." messages here
cBar being destroyed ...
cBar being destroyed ...

如果你运行上面的那个,你会看到第一个 emplace_back “就地”创建实例,但随后立即调用移动构造函数,然后调用析构函数。

更奇怪的是,在第二个位置的情况下,我看到了预期的行为:只有一个构造函数调用。

我有两个问题:

  1. 如果我只想 emplace_back 项目而不使用 push_back,为什么我需要在我的类中定义移动构造函数。

  2. 在第一个实例创建的情况下,为什么移动构造函数,然后调用析构函数?如果我访问第一个实例的数据,一切似乎都是正确的,所以我不知道为什么调用移动构造函数和析构函数。

我使用 Visual Studio 2015。

每一步输出 vector 大小:

Begin to create 2 cBar instance, I am expecting 2 "cBar being created ..." messages here
Vector size:0
cBar being created ...
Vector size:1
cBar being moved ...
cBar being destroyed ...
cBar being created ...
Vector size:2
Destroy the 2 isntances (this works, I see the two expected "cBar being destroyed ..." messages here
cBar being destroyed ...
cBar being destroyed ...

最佳答案

2.In case of the first instance creation, why the move constructor, then the destructor is called?

因为 emplace_back 插入了第二个元素导致重新分配; vector 的内部存储需要扩展,旧存储中的元素必须复制/移动到新存储,然后销毁。

您可以使用 reserve提前避免重新分配。

1.Why do I need to define a move constructor in my class if I just want to emplace_back items, and never use push_back.

正如上面的解释所说,vector需要通过复制/移动操作来移动元素。所以你必须为类定义复制或移动构造函数。 emplace_backpush_back 都是如此,因为它们都将元素添加到 vector 并可能导致重新分配。

关于c++ - emplace_back 调用移动构造函数和析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43169141/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com