Рассмотрим следующую простую программу:
struct A
{
A() { std::cout << "construct A\n"; }
~A() { std::cout << "destruct A\n"; }
};
int main()
{
A a;
}
Это печатает:
constructs A
destructs A
, как и ожидалось.
Теперь давайте добавим простую функцию:
void f(A a) {}
и назовите его:
int main()
{
A a;
f(a);
}
и мы увидим:
construct A
destruct A
destruct A
Теперь, откуда взялся этот дополнительный destruct A
? а где соответствующий construct A
? Ответ: при вызове f
вызывается конструктор копирования по умолчанию. Если вы напечатаете материал в конструкторе копирования, например:
A(A const&) { std::cout << "copy-construct A\n"; }
, вы получите вывод:
construct A
copy-construct A
destruct A
destruct A
, который показывает, что действительно, 2 объекта были построены, а затем оба уничтожаются.
С другой стороны, если f
принимает аргумент по ссылке, например так:
void f(A& a) {}
, то конструктор копирования не вызывается (поскольку копия не создается ), и результат будет:
construct A
destruct A