посторонние вызовы копи-конструктора и деструктора - PullRequest
2 голосов
/ 17 апреля 2010

[продолжение до этот вопрос ]

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?

1 Ответ

16 голосов
/ 17 апреля 2010

Чтобы ясно видеть, что происходит, я рекомендую включить указатель 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. Временный А (... ср) уничтожен.
  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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...