четверг, 14 февраля 2019 г.

Конструктор копирования в C++

Конструктор копирования в классе MyClass будет выглядеть так:
           MyClass(const MyClass &arg)
Почему const? Потому что при копировании оригинал не должен меняться. Почему параметр по ссылке передается? А потому что, если по значению, то будет происходить копирование аргумента. Т.е. в функции, которая должна копировать происходит вызов функции копирования... Бесконечная рекурсия.

Конструктор копирования вызывается
  1. При инициализации объекта
    MyClass a;
    MyClass b = a; //инициализация объекта b объектом a
  2. При передачи объекта в функцию по значению (создается копия аргумента)
  3. При возвращении по значению (создается временный объект)
(Про всё это хорошо написано в памятке C++ Notes: OOP: Copy Constructors)

Таким образом, в следующем коде конструктор копирования будет вызываться дважды
MyClass make_obj()
{
            MyClass c;
            return c;
}

int main()
{
           MyClass a = make_obj()
 }

Конструктор копирования вызывается при создании временного объекта, возвращаемого из фунции и при инициализации объекта а. 

Но. Откомпилировав программу с помощью g++ и запустив, мы увидим, что конструктор копирования ни разу не вызывается! Чтоб в этом убедиться - вставим в конструктор отладочный вывод. 

Как же так? Компилятор оптимизирует? Но флаг -O0 не помог, всё по-прежнему.

Отгадка нашлась здесь.
man GCC-4.4.7:
-fno-elide-constructors
The C++ standard allows an implementation to omit creating a temporary which is only
used to initialize another object of the same type.
Т.е. все дело действительно в оптимизации, просто отключать ее нужно специальным флагом


Комментариев нет: