Идиомы и стили С++ | страница 38
Так же добавлю, что пользуюсь при подготовке Шагов компилятором BC3.1, а он поддерживает шаблоны не вполне так, как это делают современные компиляторы. То есть, если Вы просто скопируете код, вероятно он сразу даже не откомпилируется. Так что предупреждаю - если собираетесь пользоваться шаблонами - проверьте, что на эту тему думает компилятор (а так же насчет исключений и операторов вида xxxxxxx_cast‹›()).
Мне же итератор нужен был исключительно для следующих Шагов, а совпадения фамилий, характеров и событий прошу считать случайными.
Шаг 27 - Умные указатели. Перегрузка operator*, operator(),operator-›*.
Пробегая по верхам интересных идиом я упустил одну важную вещь. Поначалу она была не так важна, но пришло время замучать и ее. Я имею в виду то, что наши замечательно умные указатели, smart pointers, вообще-то имеют неполную семантику. То есть, они не полностью имитируют обычные, настоящие указатели. За примерами не надо ходить далеко - попробуем разыменовать смарт или вызвать функцию по указателю:
>obj = *(smart_ptr);
>(obj-›*ptr_to_funct) (some_parameter);
С первой проблемой рассчитаться легко. Если Вы НЕ читаете сейчас этот Шаг, не беспокойтесь - решение придет само, в тот момент, когда задача возникнет.
>//Ясно, это реализации перегруженных операторов-селекторов.
>CSmth* operator-›() const { return prt_real; }
>CSmth& operator* () const { return *ptr_real; }
>operator CSmth* () const { return ptr_real; }
А что вторая проблема? Да, тут ситуация намного серьезнее, и если Вы опять-таки не читаете этот Шаг, то нужно немедленно прочесть его - или первоисточник - статью Мейерса в Dr. Dobb's Journal. Только там придется продираться через тучные стада шаблонов и долгих рассуждений. Без шаблона конечно не обойтись, но нужно ухватить хотя бы идею. Поэтому сделаем так, как нормальный человек читает детективы Марининой: первые и последние две страницы.
Сначала, кто такой operator-›*. Это который вызывает функцию-член по указателю. Такую функцию нужно вызывать с указанием объекта, если из другой функции-члена, то в виде (this-›*mpf)() или (*this).*mpf().
>// Этот класс используется так же дальше
>class CSmth {
>public:
> int a;
> int pf (void) {return a;}
>};
>typedef int (CSmth::*PF)(void);
Если мы нарисуем умный указатель на объект класса CSmth, определять