Будучи объявлен описанным выше образом, обобщенный конструктор копирования для SmartPtr предоставляет больше, чем нам нужно. Да, мы хотим иметь возможность создавать SmartPtr
Предполагая, что SmartPtr написан по образцу auto_ptr и tr1::shared_ptr, то есть предоставляет функцию-член get, которая возвращает копию встроенного указателя, хранящегося в объекте «интеллектуального» указателя (см. правило 15), мы можем воспользоваться реализацией шаблонного конструктора, чтобы ограничить набор преобразований:
template
class SmartPtr {
public:
template
SmartPtr(const SmartPtr& other) // инициировать этот хранимый
:heldPtr(other.get()) {...} // указатель указателем, хранящимся
// в другом объекте
T *get() const { return heldPtr;}
...
private: // встроенный указатель,
T *heldPtr; // хранящийся в «интеллектуальном»
};
Мы используем список инициализации членов, чтобы инициализировать член данных SmartPtr
Использование шаблонных функций-членов не ограничивается конструкторами. Еще одно полезное применение таких функций – поддержка присваивания. Например, класс shared_ptr из TR1 (см. правило 13) поддерживает конструирование из всех совместимых встроенных указателей, tr1::shared_ptr, auto_ptr и tr1::weak_ptr (см. правило 54), а также наличие в правой части оператора присваивания объекта любого из этих типов, кроме tr1::weak_ptr. Ниже приведен фрагмент спецификации TR1 для tr1::shared_ptr; обратите внимание, что при объявлении параметров шаблона используется ключевое слов class, а не typename. Как объясняется в правиле 42, в данном контексте они означают одно и то же.
template
public:
template
explicit shared_ptr(Y *p); // любого совместимого
template
shared_ptr(shared_ptr
template
explicit shared_ptr(weak_ptr
template
explicit shared_ptr(auto_ptr
template
explicit shared_ptr& operator=(shared_ptr
template
explicit shared_ptr& operator=(auto_ptr
... // auto_ptr
};
Все эти конструкторы объявлены как explicit, за исключением обобщенного конструктора копирования. Это значит, что неявные преобразования от одного типа shared_ptr к другому допускаются, но