4

When pushing two elements into vector, I think it should be using copy operator twice. And the destructor is used when an object deconstructs. However, the result shows that it uses copy constructor for three times and immediately uses destructor once after the pushing the objects. So what is the reason for this question ?

using namespace std;

struct X {
    X() { cout << "X()" << endl; }
    X(const X&) { cout << "X(const X&)" << endl; }
    X& operator=(const X& xr) { cout << "operator=(const X& xr)" << endl; return *this; }
    ~X() { cout << "~X()" << endl; }
};

void fcn1(X x1, X &x2, X *x3) {
    cout << "fcn1 start" << endl;

    vector<X> v1;
    cout<<"push x"<<endl;
    v1.push_back(x1);
    v1.push_back(x2);

    cout << "fcn1 end" << endl;
}
Bingchen
  • 55
  • 4

1 Answers1

8

That's because of how std::vector manages its own buffer. If you first v1.reserve(2)-ed the space, you would see no reallocations caused by inserting at most two elements, and, as expected, just two copy-constructor calls.

First, the std::vector has enough space to store only 1 element. You push_back (1st copy-c'tor) and that space is occupied. Then, you push_back again, which requires allocating more space. vector allocates more space, copies the previously inserted x1 (2nd copy-c'tor) and pushes back the x2 (3rd copy-c'tor).

If you are using C++11 and onwards, and are familiar with move semantics, you can specify a move-constructor to your class, which will likely make std::vector use it (under some specific circumstances) during the reallocations.

Fureeish
  • 12,533
  • 4
  • 32
  • 62
  • Exactly the answer I want, very clear ! Although I learned how a container manage its space, I missed this point for this problem. Thank you my friend ! – Bingchen Mar 26 '19 at 14:06