Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 [ 52 ] 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

Листинг 8. Фрагмент реализации связанного списка

I class list node;

3 class linked list 4{

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 }

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 }

25 ...

26 }; 27

28 class list node

29 {

30 linked list *owner;

31 private: Этот раздел содержит

32 friend class linked list; сообщения,получаем1е только

33 от объектов linked list

34 void remove yourself from me( list node *root )

35 {

3 6 ... Выполнить удаление

37 owner->have removed an element();

38 }

Листинг 9. Улучшенный вариант реализации связанного списка 1 class list node;

3 class linked list

5 int number of elements in list;

6 list node *root;

8 private:



9 friend class list node;

10 void have removed an element( void );

12 public:

13 void remove this node( list node *p ); 14

15 ...

16 };

17 ========================================================

18 class list node

19 {

20 linked list *owner;

21 private: Этот раздел содержит сообщения,

22 friend class linked list; получаем1е только от

23 объектов linked list

25 void remove yourself from me( list node *root );

26 };

28 ========================================================

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 }

41 ========================================================

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. Все, чего вы добились, - это устранили то, что в ином случае вызвало бы полезное сообщение об ошибке во время компиляции, и сдвинули ошибку на этап выполнения.

Исключениями из сказанного выше являются перегруженные операции и конструкторы; многие классы имеют их по нескольку, и аргументы по умолчанию часто имеют смысл в конструкторах. Код, подобный



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 [ 52 ] 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76