Вопрос о копировании объектов в C++

Jan 16, 2011 23:00


Я не программировал серьезно на C++ с третьего курса, потому разные тонкости уже подзабыл. Ни в сети, ни у Страуструпа ответа на вдруг возникший вопрос найти не могу. Вот небольшая программа:

#include using namespace std; class A { public: A() { cout << "A::A()" << endl; } A(const A&) { cout << "A::A(const A&)" << endl; } ~A() { cout << "A::~A()" << endl; } private: A& operator = (const A&); }; A FooBar() { A tmp; return tmp; } int main() { A a; A b = FooBar(); return 0; }
Я всегда считал, что она отработает следующим образом.
  1. В строчке "A a;" вызовется конструктор по умолчанию
  2. Далее внутри функции "FooBar()" вызовется конструктор по умолчанию в строчке "A tmp;"
  3. Наконец, в строчке "A b = FooBar();" будет вызван конструктор копирования, который выполнит инициализацию объекта "b" объектом "tmp".

А вот оказывается, что конструктор копирования не вызывается здесь ни разу! На печати я вижу вот что:

A::A() A::A() A::~A() A::~A()
Пожалуйста, объясните мне, что происходит в строчке "A b = FooBar();"?

Кстати, если в "main()" я пишу "A b = a;", то на печати, как и ожидается, имею

A::A() A::A(A&) A::~A() A::~A()
Использовались компиляторы g++ и xlC:

g++ -Wall -Wextra -O0 test.cpp xlC -O0 test.cpp
Upd. Оказывается, я столкнулся с так называемой Return value optimization. Следующая программа (в ней модифицирована FooBar() и ее вызов) уже выдает, то, что ожидает всякий C++-пенсионер:

#include using namespace std; class A { public: A() { cout << "A::A()" << endl; } A(A&) { cout << "A::A(A&)" << endl; } A(const A&) { cout << "A::A(const A&)" << endl; } ~A() { cout << "A::~A()" << endl; } private: A& operator = (const A&); }; A FooBar(bool b) { A t1; A t2; if (b) return t1; else return t2; } int main() { A a; A b = FooBar(true); return 0; }
Upd-2. В комментариях пишут, что такое поведение можно отключить ключом -fno-elide-constructors.

программирование

Previous post Next post
Up