418 _____ Часть III. Современное программирование на C++
запретить копирование, а последний раздел посвящен копированию в производных классах.
Когда выполняется копирование?
Издержки при копировании сложных объектов могут быть очень высокими, о чем несложно догадаться, если представить себе, насколько сложны классы, работающие с графическими объектами, управляющие развитыми структурами.данных или входящие во.множественные иерархии. Поэтому небесполезно будет выяснить, в каких ситуациях выполняются конструктор копий и операция присваивания. Поскольку по характеру своей деятельности они похожи, мы не станем рассматривать их по отдельности, а поговорим о копировании вообще.
Копирование происходит при передаче объекта по значению, т. е. когда в описании соответствующего аргумента функции не используются операция получения адреса (&) или разыменования (*). При возврате объекта по значению также имеет место копирование. Вот примеры обоих случаев:
void Foo( X arg); // X — произвольный класс Х Foo () ; // то же
Когда объект передается по значению, все производимые над ним манипуляции в действительности касаются только копии. Когда объект создается внутри функции, крайне желательно возвращать его по значению, а не по ссылке. Судите сами:
Х& Foo ()
{
Х *х = new X; // локально размещенный объект return *х;
)
В этом примере ответственность за уничтожение объекта х, размещенного в куче, ложится на окружение функции Foo, что чревато ошибками. В следующем примере объект размещается в локальном стеке функции.
Х& Foo ()
{
Х х;
return &x;
}
С этой функцией проблема состоит в том, что при завершении ее работы локальный стек очищается и автоматически вызывается деструктор для х. Итак, для объекта, порожденного внутри функции, возврат должен происходить по значению, и следует представлять, во что это обходится.