Материалы книги получены с http://www.itlibitum.ru/
Параметризованные умные указатели
Один из очевидных подходов к созданию универсальных умных указателей - использование шаблонов.
template <class Type>
class SP {
private:
Type* pointer;
public:
SP() : pointer(NULL) {}
SP(Type* p) : pointer(p) {}
operator Type*() { return pointer; }
Type* operator->() { return pointer; }
};
void f(Foo*);
Ptr<Foo> pf(new Foo);
f(pf); // Работает благодаря функции operator Type*()
pf->MemberOfFoo(); // Работает благодаря функции operator->()
Этот шаблон подойдет для любого класса, не только для класса Foo. Перед вами - одна из базовых форм умных указателей. Она используется достаточно широко и даже может преобразовать указатель на производный класс к указателю на базовый класс при условии, что вы пользуетесь хорошим компилятором.
Хороший компилятор C++ правильно обрабатывает такие ситуации, руководствуясь следующей логикой:
1. Существует ли конструктор P<Foo>, который получает Р<Ваr>? Нет. Продолжаем поиски.
2. Существует ли в Р<Ваr> операторная функция operator P<Foo>()? Нет. Ищем дальше.
3. Существует ли пользовательское преобразование от Р<Ваr> к типу, который подходит под сигнатуру какого-либо конструктора P<Foo>? Да! Операторная функция operator Bar*() превращает Р<Ваr> в Bar*, который может быть преобразован компилятором в Foo*.
Фактически выражение вычисляется как Ptr<Foo>pf2(Foo*(pb.operator Bar*())), где
преобразование Bar* в Foo* выполняется так же, как для любого другого встроенного
указателя. Как я уже говорил, все должно работать именно так, но учтите - некоторые компиляторы обрабатывают эту ситуацию неправильно. Даже в хороших компиляторах результат вложения подставляемой (inline) операторной функции operator Bar*() во встроенный P<Foo>(Foo*) может быть совсем не тем, на который вы рассчитывали; многие компиляторы создают вынесенные (а следовательно, менее эффективные) копии встроенных функций классов вместо того, чтобы генерировать вложенный код подставляемой функции. Мораль: такой шаблон должен делать то, что вы хотите, но у компилятора на этот счет может быть другое мнение.
Назад Содержание Далее
|