Avi*_*hol 4 c++ stdvector c++11 visual-studio-2015
我尝试将类cBar的两个实例置于具有emplace_back函数的向量中.
根据引用调用,emplace_back仅保留向量中的位置,然后"就地"创建新实例.
现在,我试着尝试一下:
#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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
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 ...
Run Code Online (Sandbox Code Playgroud)
如果你运行上面的那个,你将看到第一个emplace_back创建实例"就地",但然后立即调用移动构造函数,然后调用析构函数.
更奇怪的是,在第二个安慰的情况下,我看到了预期的行为:只有一个构造函数调用.
我有两个问题:
如果我只想要emplace_back项目,并且从不使用push_back,为什么我需要在我的类中定义移动构造函数.
在第一个实例创建的情况下,为什么移动构造函数,然后调用析构函数?如果我访问第一个实例的数据似乎都是正确的,所以我不知道为什么移动构造函数和析构函数被调用.
我使用Visual Studio 2015.
每步输出矢量大小:
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 ...
Run Code Online (Sandbox Code Playgroud)
2.在第一个实例创建的情况下,为什么移动构造函数,然后调用析构函数?
因为emplace_back插入第二个元素会导致重新分配; vector需要扩展的内部存储,旧存储中的元素必须被复制/移动到新存储,然后销毁.
1.如果我只想要emplace_back项目,并且从不使用push_back,我为什么需要在我的类中定义移动构造函数.
如上所述,vector需要通过复制/移动操作来移动元素.因此,您必须为类定义复制或移动构造函数.这是双方真实emplace_back和push_back,因为它们都添加元素vector,并可能导致重新分配.