|
Программирование >> Решение нетривиальных задач
26 }; 28 class list node 29 { 30 linked list *owner; 31 private: Этот раздел содержит 32 friend class linked list; сообщения,получаемые только 33 от объектов linked list 34 void remove yourself from me( list node *root ) 35 { 3 6 ... Выполнить удаление 37 owner->have removed an element(); 38 } 39 }; Листинг 9. Улучшенный вариант реализации связанного списка 1 class list node; 3 class linked list 5 int number of elements in list; 6 list node *root; 8 private: Листинг 8. Фрагмент реализации связанного списка I class list node; 3 class linked list 5 int number of elements in list; 6 list node *root; 7 8 private: этот раздел содержит сообщения, получаем1е 9 friend class list node; только от объектов list node 10 void have removed an element(void) II { 12 -number of elements in list; 13 } 14 15 public: 16 void remove this node( list node *p ) 17 { 18 Следующая строка генерирует ошибку при компиляции, 19 так как компилятор не знает, что list node 20 имеет сообщение remove yourself from me( &root ). 22 p->remove yourself from me( &root ); 23 } 24 25 9 friend class list node; 10 void have removed an element( void ); 12 public: 13 void remove this node( list node *p ); 14 15 ... 17 }}/ 18 class list node 19 { 20 linked list *owner; 21 private: Этот раздел содержит сообщения, 22 friend class linked list; получаемые только от 23 объектов linked list 25 void remove yourself from me( list node *root ); 2278 ======================================================== 29 функции класса linked list: 30 ======================================================== 31 inline void linked list::remove this node( list node *p ) 32 { 33 p->remove yourself from me( &root ); 34 } 35 --------------------------------------------------------36 inline void linked list::have removed an element( void ) 37 { 38 --number of elements in list; 39 } 4401 ======================================================== 42 функции класса list node: 43 ======================================================== 44 void list node::remove yourself from me( list node *root ) 45 { 4 6 ... Выполнить удаление 47 owner->have removed an element(); 48 } 116. Избегайте перегрузки функций и аргументов, используемых по умолчанию Это правило не применяется к конструкторам и функциям перегрузки операций. Перегрузка функций, подобно многим другим свойствам Си++, была добавлена к этому языку по особым причинам. Не позволяйте себя увлечь этим. Функции, которые делают разные вещи, должны иметь и разные имена. Перегруженные функции обычно вызывают больше проблем, чем их решают. Во-первых, проблема двусмысленности: f( int, long ); f( long, int ); f( 10, 10 ); ОШИБКА: Какую из функций я вызываю? Более коварно следующее: f( int ); f( void* ); f( 0 ); ОШИБКА: Вызов двусмысленный Проблемой здесь является Си++, который считает, что 0 может быть как указателем, так и типом int. Если вы делаете так: const void *NULL = 0; const int ZERO = 0; то вы можете записать f(NULL) для выбора варианта с указателем и f(ZERO) для доступа к целочисленному варианту, но это ведет к большой путанице. В такой ситуации вам бы лучше просто использовать функции с двумя разными именами. Аргументы по умолчанию, создающие на самом деле перегруженные функции (по одной на каждую возможную комбинацию аргументов), также вызывают проблемы. Например, если вы написали: f( int x = 0 ); и затем случайно вызвали f() без аргументов, компилятор успешно и без возражений вставит 0. Все, чего вы добились, - это устранили то, что в ином случае вызвало бы полезное сообщение об ошибке во время компиляции, и сдвинули ошибку на этап выполнения. Исключениями из сказанного выше являются перегруженные операции и конструкторы; многие классы имеют их по нескольку, и аргументы по умолчанию часто имеют смысл в конструкторах. Код, подобный
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |