|
Копирование Ой! Опять эти проклятые пользователи... MP<Foo> mpf1; // Создает Foo, на который ссылается указатель MP<Foo> mpf2 = mpf1; // Неудача! Пусть знак равенства не вводит вас в заблуждение - здесь происходит конструирование, и эта строка эквивалентна строке MP<Foo> mpf2(mpfl);. Если не перегрузить конструктор копий и разрешить компилятору C++ внести свою лепту, мы получим два ведущих указателя, которые ссылаются на один и тот же объект Foo. По умолчанию конструктор копий, генерируемый компилятором, радостно копирует содержащийся в переменной адрес из старого указателя в новый. Проблема решается относительно просто. template <class Type> class MP { private: Type* t; public: MP(); // Нормальный MP(const MP<Type>& mp) : t(*(mp.t)) {} // Конструктор копий }; Этот конструктор копий создает дубликат указываемого объекта, используя для этого конструктор копий указываемого объекта. Получается не очень эффективно, но работает. В некоторых ситуациях, с которыми мы столкнемся позже, лучше вообще запретить копирование. Проще всего для этого объявить конструктор копий закрытым и не назначать ему никаких действий. template <class Type> class MP { private: Type* t; MP(const MP<Type>&) : t(NULL) {} // Никогда не будет вызываться public: MP(); }; Тем самым мы предотвращаем непреднамеренное копирование в ситуациях вроде следующей: void f(MP<Foo>); MP<Foo> mpf; f(mpf); // Создается временная копия Для предотвращения копирования также можно воспользоваться дескрипторами, о которых будет рассказано ниже. |
Copyright 2005. Климов Александр. All Right Reserved.