c++ - 为什么仅当 vector 中已有元素时才调用移动构造函数?

标签 c++ c++11 vector back emplace

我正在尝试学习 C++11 中的新功能。我正在 XCode 中测试以下代码。

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

class CClass
{
    std::string s;
public:
    CClass()
    {
        std::cout<<"Default Constructor"<<std::endl;
    }
    CClass(const std::string v) :s(v) {
        std::cout<<"Constructor"<<std::endl;
    }

    CClass(const CClass& other): s(other.s) {
        std::cout<<"Copy Constructor"<<std::endl;
    }
    CClass(CClass&& a) noexcept
    {
        std::cout<<"Move Constructor"<<std::endl;
        s = std::move(a.s);
    }
    CClass& operator = (const CClass& other)noexcept
    {
        std::cout<<"Copy Assignment"<<std::endl;
        if(this != &other)
        {
            s = other.s;
        }
        return *this;
    }
    CClass& operator = (CClass&& other) noexcept
    {
        std::cout<<"Move Assignment"<<std::endl;
        if(this != &other)
        {
            s = std::move(other.s);
        }
        return *this;
    }
};

int main()
{
    std::vector<CClass> v;
    CClass x("hello");
    //v.push_back(x);
    std::cout<<"--------------------"<<std::endl;
    v.emplace_back("uiuiu");
    std::cout<<"--------------------"<<std::endl;
}

当我取消对推送的注释时,我得到以下结果:

Constructor
Copy Constructor
--------------------
Constructor
Move Constructor
--------------------

否则,如果我评论它,我会得到:

Constructor
--------------------
Constructor
--------------------

我的问题是为什么在第二种情况下没有调用移动构造函数?它仅在 vector 最初不为空的第一种情况下被调用。

最佳答案

这是因为 vector 中的一个元素需要移动到一个新的内存位置。发生这种情况的原因是新大小会超过 vector 容量,因此必须为 vector 分配具有新容量的新内存。

来自 std::vector::emplace_back :

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.

迭代器和引用失效的原因相同:因为元素现在存储在内存中的新位置。

如果您在第一种情况下调用 reserve,您将看到没有调用移动构造函数:

CClass x{"hello"}; // constructor
v.reserve(2); // make space for 2 elements (you could have also used resize)
v.push_back(x); // copy constructor
v.emplace_back("uiuiu"); // constructor

关于c++ - 为什么仅当 vector 中已有元素时才调用移动构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44891023/

相关文章:

C++ 对多个类使用相同的 ADT 结构

c++ - 每线程单例使用 thread_local 存储

c++ - 是否可以从模板参数中提取数组大小?

c++ - 为什么在调用构造函数后会崩溃?我正在尝试将shared_ptr推回 vector

c++ - npm 安装 : fatal error C1083 on bson and kerberos compilation 上的 node-gyp 错误

c++ - 快速像素访问 opencv

c++ - 使用 MSVC 14.0 (VS 2015) 编译 Boost 时编译器版本未知

<IMG> 上的 CSS 背景颜色使用外部 SVG 作为 SRC

python - numpy 矩阵向量乘法

ios - iOS从PDF提取矢量图形