Идея ясная. Нужно переопределить все восемь, или не переопределять их вовсе. Вопрос в том, направлен ли Ваш указатель на массив, или нет. Во всяком случае, не спешите с этим. Да, и в Ваших плюсах скорее всего тип ptrdiff_t надо заменить на ptr_diff. Я просто дома на BC3.1 все проверяю.
Что здесь хорошего? Мы получили класс объектов-указателей, которые можно смело применять вместо настоящих. Деструктор ~CPthat() уничтожает указуемый объект, поскольку сам по себе последний не имеет имени, и без своего указателя утрачивает идентичность. Проще говоря, останется в нашей памяти навечно, как герой. Ну можно конечно вызывать деструктор и явно, а что? Вот так:
pthat-›~Cthat();
Тогда удаление уберите из деструктора указателя.
Напоследок сделаем очевидный шаг - сделаем умный указатель параметризированным классом.
template ‹class T›
class SmartPointer {
private:
T* tObj;
public:
SmartPointer(T* _t=NULL):tObj(_t);
~SmartPointer(){ if (tObj) delete tObj; }
operator T*(){ return tObj; }
T* operator-›(){ return tObj; }
};
Для интереса посмотрите, как сделан auto_ptr в STL.
Передохнем. Кофе. Джоггинг. Пиво. Сигарета. Нужное подчеркнуть, выпить, покурить.
Шаг 3 - Как это применять.Берем код параметризированного класса.
template ‹class T›
class SmartPointer {
private:
T* tObj;
public:
SmartPointer(T* _t=NULL): tObj(_t);
~SmartPointer() {if (tObj) delete tObj;}
operator T*(){return tObj;}
T* operator-›(){return tObj;}
};
1. Обработка обращения к NULL.Заменяем реализацию оператора -› на:
T* operator-›() {
if (!tObj) {
cerr ‹‹ "NULL";
tObj = new T;
}
return tObj;
}
или
T* operator-›() {
if (!tObj) throw CError;
return tObj;
};
Здесь CError класс исключения. Или втыкаем статический экземпляр-шпион.
private:
T* tObj; // Это было;
static T* spy; // Это добавлено
Ну и сам перегруженный оператор.
T* operator-›() {
if (!tObj) return spy;
return tObj;
};
Комментарии к книге «Идиомы и стили С++», Albert Makhmutov
Всего 0 комментариев