mercredi 20 mai 2020

std::move triggered destructor?

I'm adapting to an interface with parameter const vector<pair<int32_t, A>>& as.

To avoid multi-construct and multi-destruct, I write CreateAs as follow.

I was expecting it to trigger create move del each for once, but it turned out triggered move and del for twice.

  • What's the reason?
  • I made this way so that the A objects could destroy themselves automatically, even with new but without delete. Am I doing it right?

To reproduce it: https://repl.it/@unix1/ShrillFirsthandAdvance

#include <iostream>
#include <vector>

using namespace std;

struct A {
    A() { cout << "A()" << endl; }
    A(int32_t a) : a_(a) { cout << "Create A: " << a << endl; }
    A(const A& oa) { a_ = oa.a_; cout << "Copy A: " << oa.a_ << endl; }
    A(A& oa) { a_ = oa.a_; cout << "Copy A non-const: " << oa.a_ << endl;  }
    A(const A&& oa) { a_ = oa.a_; cout << "Move A: " << oa.a_ << endl; }
    A(A&& oa) { a_ = oa.a_; cout << "Move A non-const: " << oa.a_ << endl; }
    ~A() { cout << "Del A: " << a_ << ", ptr: " << this << endl; }

    int32_t a_;
};

void CreateAs(vector<pair<int32_t, A>>& as) {

    as.reserve(3);
    for (int32_t i = 0; i < 3; ++i) {
        A* a = new A(i*i);
        cout << "a ptr: " << &a << endl;
        cout << "-----before insert----" << endl;
        as.emplace_back(make_pair(i, move(*a)));
        cout << "-----after insert-----" << endl;
    }
}

void Test() {
    vector<pair<int32_t, A>> as;
    cout << "-----Create begin----" << endl;
    CreateAs(as);
    cout << "-----Create end------" << endl;
    for (const auto& item : as) {
        cout << item.first << "->" << item.second.a_ << endl;
    }
}

int main(int32_t argc, char* argv[]) {
    Test();
    cout << "____end test____" << endl;
    return 0;
}

Aucun commentaire:

Enregistrer un commentaire