Идиомы и стили С++ [Albert Makhmutov] (fb2) читать постранично, страница - 2
[Настройки текста] [Cбросить фильтры]
- 1
- 2
- 3
- 4
- . . .
- последняя (22) »
class CPthat { private: Cthat* aThat; public: CPthat(Cthat* _that=NULL):aThat(_that){} ~CPthat() { if (aThat) delete aThat; } operator Cthat* () { return aThat;} // Оператор преобразования типа CThat* operator-›() { return aThat; }; // Оператор селектора -› CPthat operator+(ptrdiff_t _offset) { return CPthat(aThat+_offset); } // ^^^^^^^^^ };
int main () { Cthat* aThat = new Cthat; aThat-›doSomething(); CPthat pthat(new Cthat); pthat-›doIt(); // Вариант обращения через -› ((Cthat*)pthat)-›doIt (); //Вариант обращения через Cthat* delete aThat; return 0; } Что получилось: Имеем класс Cthat, который может иметь экземпляры, хотя и не имеет наполнения, и может исполнить пустую функцию. (Обратите внимание. Пустой объект имеет размер 1, и если добавить переменную char, то размер будет тот же. Экземпляры пустых объектов существуют, и они различаются.) Имеем класс объекта-указателя CPthat, в котором храним обычный указатель, но доступ к нему ограничиваем, и перегружаем для него операторы: 1. приведения типа Cthat 2. member selector -›. 3. Операторы арифметики указателей. Я указал только один, сложение. Идея ясная. Нужно переопределить все восемь, или не переопределять их вовсе. Вопрос в том, направлен ли Ваш указатель на массив, или нет. Во всяком случае, не спешите с этим. Да, и в Ваших плюсах скорее всего тип 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; }; Здесь нужно пояснить: spy совсем не обязательно класса T. Можно воткнуть производный, и переопределить его функции. Тогда он будет Вам докладывать о попытках обращения к NULL. Не забудьте его создать, инициализировать, и прицепить к указателю. А то вся идея на помойку. Вы пытаетесь отловить обращение к NULL, а там… NULL!!! "Матрицу" видели?2. Отладка и трассировка.
Ну это совсем банально. Выносим определение операторов за определение класса и ставим там точку останова. Чтобы не тормозило в релиз версии, окружаем слово inline ифдефами. template ‹class T› #ifndef DEBUG inline #endif SmartPointer‹T›::operator T*() { return tObj; }template ‹class T› #ifndef DEBUG inline #endif T* SmartPointer‹T›::operator T-›() { return tObj; }
3. Статистика классов и объектов.
Ну все, здесь уже совсем все просто. Ничего писать не буду, кроме напоминания о том, что всенепременнейше нужно определять статистические переменные класса, в том числе- 1
- 2
- 3
- 4
- . . .
- последняя (22) »
Последние комментарии
43 минут 46 секунд назад
15 часов 25 минут назад
15 часов 25 минут назад
20 часов 44 минут назад
1 день 26 минут назад
1 день 47 минут назад