Анимация
JavaScript
|
Главная Библионтека 42 return row( the array + (ncols * index) ); 43 } 44 ======================================================== 45 функции- члены класса int array::row 46 ======================================================== 47 inline int &int array::row::operator[]( int index ) 48 { 49 return first cell in row[ index ]; 50 } 52 ======================================================== 53 void main ( void ) ..* 54 { 55 int array ar(10,20); то же самое, что и ar[10][20], но 55 размерность во время компиляции 56 ar[1][2] = 100; может быть не определена. 57 cout << ar[1][2]; 59 } В соответствии со стандартом должно быть int main ( void ). - Ред. Часть 8в. Ссылки 120. Ссылочные аргументы всегда должны быть константами 1 21 . Никогда не используйте ссылки в качестве результатов, пользуйтесь указателями Использование ссылочных аргументов в языке программирования вызвано четырьмя причинами: • Они нужны вам для определения конструктора копии. • Они нужны вам для определения перегруженных операций. Если вы определили: some class *operator+( some class *left, some class *right ); то вы должны сделать такое дополнение: some class x, y; x = *(&x + &y) Использование ссылок для аргумента и возвращаемого значения позволяет вам написать: x=x+1; • Вы часто хотите передать объекты по значению, исходя из логики. Например, вы обычно в функцию передаете тип double, а не указатель на double. Тем не менее, тип double представляет собой 8-байтовую упакованную структуру с тремя полями: знаковым битом, мантиссой и порядком. Передавайте в этой ситуации ссылку на константный объект. • Если объект какого-нибудь определенного пользователем класса обычно передается по значению, то используйте вместо этого ссылку на константный объект, чтобы избежать неявного вызова конструктора копии. Ссылки в языке не предназначены для имитации Паскаля и не должны использоваться так, как используются в программе на Паскале. Проблема ссылочных аргументов - сопровождение. В прошлом году один из наших сотрудников написал следующую подпрограмму: void copy word( char *target, char *&src ) src является сс1лкой на char* while( isspace(*src) ) ++src; Инкрементировать указатель, на который сс1лается src. while( *src && !isspace(*src) ) *target++ = *src++; Передвинуть указатель, на котор1й ссылается src, за текущее слово. Автор полагал, что вы будете вызывать copy word() многократно. Каждый раз подпрограмма копировала бы следующее слово в буфер target и продвигала бы указатель в источнике. Вчера вы написали следующий код: f( const char *p ) char *p = new char[1024]; load( p ); char word[64]; copy word( word, p ); delete(p); Сюрприз!p был модифицирован, поэтому весь } этот участок памяти обращается в кучу мусора! Главная проблема состоит в том, что, глядя на вызов copy word( word, p ), вы не получаете подсказки о возможном изменении p в подпрограмме. Чтобы добраться до этой информации, вы должны взглянуть на прототип этой функции (который, вероятно, скрыт на 6-ом уровне вложенности в заголовочном файле). Огромные проблемы при сопровождении. Если что-то похоже на обычный вызов функции Си, то оно должно и действовать как вызов обычной функции Си. Если бы автор copy word() использовал указатель для второго аргумента, то вызов выглядел бы подобным образом: copy word( word, &p ); Этот дополнительный знак & является решающим. Средний сопровождающий программист полагает, что единственная причина передачи адреса локальной переменной в другую функцию состоит в том, чтобы разрешить функции модифицировать эту локальную переменную. Другими словами, вариант с указателем является самодокументирующимся; вы сообщаете своему читателю, что этот объект изменяется функцией. Ссылочный аргумент не дает вам такой информации. 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 |