посторонние вызовы конструктора копирования и деструктора

[дополнение к этому вопросу ]

class A
{
    public:
         A()          {cout<<"A Construction"     <<endl;}
         A(A const& a){cout<<"A Copy Construction"<<endl;}
        ~A()          {cout<<"A Destruction"      <<endl;}
};

int main() {
    {
        vector<A> t;
        t.push_back(A());
        t.push_back(A());   // once more
    }
}

Результат:

A Construction        // 1
A Copy Construction   // 1
A Destruction         // 1
A Construction        // 2
A Copy Construction   // 2
A Copy Construction   // WHY THIS?
A Destruction         // 2
A Destruction         // deleting element from t
A Destruction         // deleting element from t
A Destruction         // WHY THIS?

person Lazer    schedule 17.04.2010    source источник


Ответы (1)


Чтобы четко видеть, что происходит, я рекомендую включить в вывод указатель this, чтобы определить, какой A вызывает метод.

     A()          {cout<<"A (" << this << ") Construction"     <<endl;}
     A(A const& a){cout<<"A (" << &a << "->" << this << ") Copy Construction"<<endl;}
    ~A()          {cout<<"A (" << this << ") Destruction"      <<endl;}

Результат, который у меня есть,

A (0xbffff8cf) Construction
A (0xbffff8cf->0x100160) Copy Construction
A (0xbffff8cf) Destruction
A (0xbffff8ce) Construction
A (0x100160->0x100170) Copy Construction
A (0xbffff8ce->0x100171) Copy Construction
A (0x100160) Destruction
A (0xbffff8ce) Destruction
A (0x100170) Destruction
A (0x100171) Destruction

Таким образом, поток можно интерпретировать как:

  1. Создается временный A (…cf).
  2. Временный A (…cf) копируется в вектор (…60).
  3. Временный A (…cf) уничтожается.
  4. Создается еще один временный A (…ce).
  5. Вектор расширяется, и старый A (…60) в этом векторе копируется на новое место (…70)
  6. Другой временный A (…ce) копируется в вектор (…71).
  7. Все ненужные копии A (…60, …ce) теперь уничтожаются.
  8. Вектор уничтожен, поэтому A (…70, …71) внутри тоже уничтожены.

Шаг 5 исчезнет, ​​если вы это сделаете.

    vector<A> t;
    t.reserve(2); // <-- reserve space for 2 items.
    t.push_back(A());
    t.push_back(A());

Вывод станет:

A (0xbffff8cf) Construction
A (0xbffff8cf->0x100160) Copy Construction
A (0xbffff8cf) Destruction
A (0xbffff8ce) Construction
A (0xbffff8ce->0x100161) Copy Construction
A (0xbffff8ce) Destruction
A (0x100160) Destruction
A (0x100161) Destruction
person kennytm    schedule 17.04.2010