vendredi 29 septembre 2017

Why is the copy constructor called when initializing and resizing a vector?

I am trying to understand better how copy and move constructors work, so I wrote this piece of code:

#include <iostream>
#include <vector>

class MyClass {
public:
    int x;

    MyClass(int i) : x(i) {
        std::cout << "Standard constructor - x=" << x << std::endl;
    }
    MyClass(const MyClass& other) : x(other.x) {
        std::cout << "Copy constructor - x=" << x << std::endl;
    }
    MyClass(MyClass&& other) : x(other.x) {
        std::cout << "Move constructor - x=" << x << std::endl;
    }
    ~MyClass() {}
};

int main() {
    std::cout << "   Initialization list:" << std::endl;
    std::vector<MyClass> v {MyClass(1), MyClass(2)};
    std::cout << "   push_back:" << std::endl;
    v.push_back(MyClass(3));
    std::cout << "   emplace_back:" << std::endl;
    v.emplace_back(4);
    return 0;
}

And here is what I obtained, using g++ version 4.8.4, on Ubuntu 14.04:

$ g++ -std=c++11 -o my_prgm my_file.cpp && ./my_prgm
Initialisation list:
   Standard constructor - x=1
   Standard constructor - x=2
   Copy constructor - x=1
   Copy constructor - x=2
push_back:
   Standard constructor - x=3
   Move constructor - x=3
   Copy constructor - x=1
   Copy constructor - x=2
emplace_back:
   Standard constructor - x=4

There are a few things that are not clear to me:

  • When initializing the vector, why is the copy constructor called? I thought that MyClass(.), being an rvalue, would be moved rather than copied.

  • When calling push_back, I assume that there is some kind of resizing that happens in the background, which is why two new objects are created. However I do not understand why, once again, the copy constructor is used instead of the move constructor.

Aucun commentaire:

Enregistrer un commentaire