|
Программирование >> Решение нетривиальных задач
1 class base 3 cls obj; 4 public: 5 virtual 6 ~base ( void ); 7 base ( void ); 8 base ( const base &r ); 9 10 const base &operator=( const base &r ); 11 private: 12 }; 13 ------------------------------------------------14 /* виртуальный */ base:: ~base( void ) 15 { 16 } 17 ------------------------------------------------18 inline base::base( void ) : obj( value ) 19 { 20 } 21 /-------------------------------------------------22 inline base::base( const base &r ) : obj( r.obj ) 23 {} 24 ------------------------------------------------25 inline const bases base::operator=( const base &r 26 { 27 if( this != &r ) 93. Пользуйтесь контрольными таблицами Одной из причин того, что Си++ имеет такую крутую кривую обучения, заключается в том, что вы должны отслеживать большое количество деталей, чтобы выполнить даже простые задачи. Просто забыть что-то, даже если вы это сделаете не надолго. Я решаю эту проблему, применяя повсюду несколько образцовых шаблонных файлов - по одному для каждой распространенной ситуации. (У меня есть один для определения базового класса, один - для определения производного класса, и т.д.). Я начинаю с копирования соответствующего шаблона в свой текущий рабочий файл и затем использую возможности своего редактора по поиску и замене для заполнения пустот. Я также перемещаю подходящие функции в файлы .cpp, когда нужно, и т.п.. Листинги 5 и 6 показывают простые шаблонные (в смысле естественного языка, а не языка С++) файлы для базового и производного классов (где кое-что опущено по сравнению с теми, которыми я пользуюсь на самом деле, но идею вы поняли). Листинг 5. base.tem - контрольная таблица для определения базового класса 1 class 3 cls obj; 4 public: 5 virtual 6 -derived ( void ); 7 derived ( void ); 8 derived ( const derived& r ); 10 const derived &operator=( const derived &r ); 12 private: 13 }; 14 ------------------------------------------------------15 /* виртуальный */ derived:: ~derived( void ) 16 { 17 } 18 ------------------------------------------------------19 inline derived::derived( void ) : base( value ) , 20 obj( value ) 21 { 22 } 23 ------------------------------------------------------24 inline derived::derived( const derived &r ) : base ( r ), 25 obj( r.obj ) 26 {} 27 ------------------------------------------------------28 inline const derived& derived::operator=( const derived &r ) 29 { 30 if( this != &r ) 31 { 32 *((base *)this) = r; 33 obj = r.obj; 34 } 35 return *this; 36 } 28 { 2 9 obj = r.obj; 30 } 31 return *this; 32 } Листинг 6. derived.tem - контрольная таблица для определения производного класса derived : public base 4 Чтобы быть строго корректным, по крайней мере на языке вхражений Си++, я должен называть поле компонентом данных-членов . Однако довольно неудобно говорить компонент данных-членов name , поэтому буду использовать просто поле , когда его значение ясно из контекста. 94. Сообщения должны выражать возможности, а не запрашивать информацию Объектно-ориентированные и структурные системы склонны подходить к проблемам с диаметрально противоположных направлений. Возьмите в качестве примера скромную запись employee. В структурных системах вы бы использовали тип struct и имели бы доступ к полям этого типа повсюду из своей программы. Например, код для печати записи мог бы свободно повторяться в нескольких сотнях мест программы. Если вы меняете что-то в основе, вроде изменения типа поля name с массива char на 16-битные символы Unicode, то вы должны разыскать каждую ссылку на name и модифицировать ее для работы с новым типом. В хорошо спроектированной объектно-ориентированной системе было бы невозможно получить доступ к полю name.4 Позвольте мне повторить это, потому что эта концепция так фундаментальна: невозможно получить доступ к полю внутри объекта, даже такому простому, как name в объекте employee. Скорее всего вы попросите employee проявить какую-нибудь способность, такую как напечатать себя , сохранить себя в базе данных или модифицировать себя, взаимодействуя с пользователем . В этом последнем случае обработчик сообщений вывел бы диалоговое окно, которое бы использовалось пользователем для ввода или изменения данных. Главным преимуществом этого подхода является то, что отправитель сообщения может меньше волноваться о том, как организовано внутреннее хранение данных. Пока объект может себя печатать, модифицировать или делать что-нибудь еще - проблемы нет. Вы можете перевести name на Unicode, не затрагивая отправителя сообщения. Этот вопрос рассматривается далее во многих правилах этой главы книги. 95. Вам обычно не удастся переделать имеющуюся структурную программу в объектно-ориентированную Одним из побочных эффектов только что описанной организации является то, что обычно невозможно преобразовать структурный подход в соответствии с этим образом мыслей без полного переписывания кода.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |