418 _____ Часть III. Современное программирование на C++

запретить копирование, а последний раздел посвящен копированию в производных классах.

Когда выполняется копирование?

Издержки при копировании сложных объектов могут быть очень высокими, о чем несложно догадаться, если представить себе, насколько сложны классы, работающие с графическими объектами, управляющие развитыми структурами.данных или входящие во.множественные иерархии. Поэтому небесполезно будет выяснить, в каких ситуациях выполняются конструктор копий и операция присваивания. Поскольку по характеру своей деятельности они похожи, мы не станем рассматривать их по отдельности, а поговорим о копировании вообще.

Копирование происходит при передаче объекта по значению, т. е. когда в описании соответствующего аргумента функции не используются операция получения адреса (&) или разыменования (*). При возврате объекта по значению также имеет место копирование. Вот примеры обоих случаев:

void Foo( X arg); // X — произвольный класс Х Foo () ; // то же

Когда объект передается по значению, все производимые над ним манипуляции в действительности касаются только копии. Когда объект создается внутри функции, крайне желательно возвращать его по значению, а не по ссылке. Судите сами:

Х& Foo ()

{

Х *х = new X; // локально размещенный объект return *х;

)

В этом примере ответственность за уничтожение объекта х, размещенного в куче, ложится на окружение функции Foo, что чревато ошибками. В следующем примере объект размещается в локальном стеке функции.

Х& Foo ()

{

Х х;

return &x;

}

С этой функцией проблема состоит в том, что при завершении ее работы локальный стек очищается и автоматически вызывается деструктор для х. Итак, для объекта, порожденного внутри функции, возврат должен происходить по значению, и следует представлять, во что это обходится.