Программирование >>  Решение нетривиальных задач 

1 ... 53 54 55 [ 56 ] 57 58 59 ... 77


4443 /}/========================================================

45 функции-члены класса int array::row

46 ========================================================

47 inline int &int array::row::operator[]( int index )

48 {

49 return first cell in row[ index ];

50 } 51

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. Ссылочные аргументы всегда должны быть константами

121. Никогда не используйте ссылки в качестве результатов, пользуйтесь указателями

Использование ссылочных аргументов в языке программирования вызвано четырьмя причинами:

Они нужны вам для определения конструктора копии.

Они нужны вам для определения перегруженных операций. Если вы определили:

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 является

ссылкой на char*

while( isspace(*src) )

++src; Инкрементировать указатель,

на который ссылается src. while( *src && !isspace(*src) )

*target++ = *src++; Передвинуть указатель,

на который ссылается 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 б1л модифицирован, поэтому весь } этот участок памяти обращается в кучу

мусора!

Главная проблема состоит в том, что, глядя на вызов copy word( word, p ), вы не получаете подсказки о возможном изменении p в подпрограмме. Чтобы добраться до этой информации, вы должны взглянуть на прототип этой функции (который, вероятно, скрыт на 6-ом уровне вложенности в заголовочном файле). Огромные проблемы при сопровождении.

Если что-то похоже на обычный вызов функции Си, то оно должно и действовать как вызов обычной функции Си. Если бы автор copy word() использовал указатель для второго аргумента, то вызов выглядел бы подобным образом:

copy word( word, &p );

Этот дополнительный знак & является решающим. Средний сопровождающий программист полагает, что единственная причина передачи адреса локальной переменной в другую функцию состоит в том, чтобы разрешить функции модифицировать эту локальную переменную. Другими словами, вариант с указателем является самодокументирующимся; вы сообщаете своему читателю, что этот объект изменяется функцией. Ссылочный аргумент не дает вам такой



1 ... 53 54 55 [ 56 ] 57 58 59 ... 77

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика