Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
В следующей версии мы разрешим оператору operator[] возвращать указатель на соответствующий элемент:
class vector {
int sz; // размер
double* elem; // указатель на элемент
public:
// ...
double* operator[](int n) { return &elem[n]; } // возвращаем
// указатель
};
При таком определении мы можем записывать элементы.
vector v(10);
for (int i=0; i<v.size(); ++i) { // работает, но по-прежнему
// некрасиво
*v[i] = i;
cout << *v[i];
}
Здесь выражение v[i] интерпретируется как вызов оператора v.operator[](i) и возвращает указатель на элемент вектора v с номером i. Проблема в том, что теперь мы должны написать оператор *, чтобы разыменовать указатель, ссылающийся на этот элемент. Это так же некрасиво, как и функции set() и get(). Проблему можно устранить, если вернуть из оператора индексирования ссылку.
class vector {
// ...
double& operator[ ](int n) { return elem[n]; } // возвращаем
// ссылку
};
Теперь можем написать следующий вариант.
vector v(10);
for (int i=0; i<v.size(); ++i) { // работает!
v[i] = i; // v[i] возвращает ссылку на элемент с номером i
cout << v[i];
}
Мы обеспечили традиционные обозначения: выражение v[i] интерпретируется как вызов оператора v.operator[](i) и возвращает ссылку на элемент вектора v с номером i.
18.4.1. Перегрузка ключевого слова const
Функция operator[](), определенная выше, имеет один недостаток: ее нельзя вызвать для константного вектора. Рассмотрим пример.
void f(const vector& cv)
{
double d = cv[1]; // неожиданная ошибка
cv[1] = 2.0; // ожидаемая ошибка
}
Причина заключается в том, что наша функция vector::operator[]() потенциально может изменять объект класса vector. На самом деле она этого не делает, но компилятор об этом не знает, потому что мы забыли сообщить ему об этом. Для того чтобы решить эту проблему, необходимо предусмотреть функцию-член со спецификатором const (см раздел 9.7.4). Это легко сделать.
class vector {
// ...
double& operator[](int n); // для неконстантных векторов
double operator[](int n) const; // для константных векторов
};
Очевидно, что мы не могли бы вернуть ссылку типа double& из версии со спецификатором const, поэтому возвращаем значение типа double. С таким же успехом мы могли бы вернуть ссылку типа const double &, но, поскольку объект типа double невелик, не имеет смысла возвращать ссылку (см. раздел 8.5.6), и мы решили вернуть значение. Теперь можно написать следующий код:
void ff(const vector& cv, vector& v)
{
double d = cv[1]; // отлично (использует константный вариант [ ])
cv[1] = 2.0; // ошибка (использует константный вариант [ ])
double d = v[1]; // отлично (использует неконстантный вариант [ ])
v[1] = 2.0; // отлично (использует неконстантный вариант [ ])
}
Поскольку объекты класса vector часто передаются по константной ссылке, эта версия оператора operator[]() с ключевым словом const является существенным дополнением.
18.5. Массивы

• Как глобальные переменные (правда, использование глобальных переменных часто является плохой идеей).
• Как локальные переменные (однако массивы накладывают на них серьезные ограничения).
• Как аргументы функции (но массив не знает своего размера).
• Как член класса (хотя массивы, являющиеся членами класса, трудно инициализировать).


const int max = 100;
int gai[max]; // глобальный массив (из 100 чисел типа int);
// "живет всегда"
void f(int n)
{
char lac[20]; // локальный массив; "живет" до конца области
// видимости
int lai[60];
double lad[n]; // ошибка: размер массива не является константой
// ...
}
Обратите внимание на ограничение: количество элементов именованного массива должно быть известно на этапе компиляции. Если мы хотим, чтобы количество элементов массива было переменным, то должны разместить его в свободной памяти и обращаться к нему через указатель. Именно так поступает класс vector с массивами элементов.
Как и к элементам массивов, размещенных в свободной области, доступ к элементам именованных массивов осуществляется с помощью операторов индексирования и разыменования ([ ] и *). Рассмотрим пример.
void f2()
{
char lac[20]; // локальный массив; "живет" до конца области
// видимости
lac[7] = 'a';
*lac = 'b'; // эквивалент инструкции lac[0]='b'
lac[–2] = 'b'; // ??
lac[200] = 'c'; // ??
}

Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Гость Татьяна24 сентябрь 22:20 Как то не очень... Невеста по ошибке. Я не дам тебе развод - Майя Линн
-
Римма24 сентябрь 21:52 Почему главные героинитпкие идиотки? И сюжет не плохой, и написано хорошо. Но как героиня - так дура дурой.... Хозяйка маленького дома, или Любимая для дракона - Кира Рамис
-
Римма20 сентябрь 12:27 Много ненужных пояснений и отступлений. Весь сюжет теряет свою привлекательность. Героиня иногда так тупит, что читать не... Хозяйка приюта для перевертышей и полукровок - Елена Кутукова