Рейтинговые книги
Читем онлайн Освой самостоятельно С++ за 21 день. - Джесс Либерти

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 103 104 105 106 107 108 109 110 111 ... 170

Почему бы не описать все классы, объекты которых используются в других классах, друзьями этих классов?

Объявление одного класса другом какого-либо иного открывает закрытые методы и данные класса, что снижает инкапсуляцию класса. Лучше всего держать как можно больше членов одного класса закрытыми от всех остальных классов.

Если функция перегружается, нужно ли описывать каждый вариант этой функции другом класса?

Да. Если вы перегружаете функцию и хотите представить все варианты этой функции друзьями другого класса, то в описании класса каждый вариант функции должен сопровождаться ключевым словом friend.

Коллоквиум

В этом разделе предлагаются вопросы для самоконтроля и укрепления полученных знаний и приводится несколько упражнений, которые помогут закрепить ваши практические навыки. Попытайтесь самостоятельно ответить на вопросы теста и выполнить задания, а потом сверьте полученные результаты с ответами в приложении Г. Не приступайте к изучению материала следующей главы, если для вас остались неясными хотя бы некоторые из вопросов, предложенных ниже.

Контрольные вопросы

1. Как объявить класс, являющийся частным проявлением другого класса?

2. Как объявить класс, объекты которого должны использоваться в качестве переменных-членов другого класса?

3. В чем состоят различия между вложением и делегированием?

4. В чем состоят различия между делегированием и выполнением класса в пределах другого класса?

5. Что такое функция-друг?

6. Что такое класс-друг?

7. Если класс Dog является другом Boy, то можно ли сказать, что Boy — друг Dog?

8. Если класс Dog является другом Boy, а Terrier произведен от Dog, является ли Terrier другом Boy?

9. Если класс Dog является другом Boy, а Boy — другом House, можно ли считать Dog другом House?

10. Где необходимо размещать объявление функции-друга?

Упражнения

1. Объявите класс Animal, который содержит переменную-член, являющуюся объектом класса String.

2. Объявите класс BoundedArray, являющийся массивом.

3. Объявите класс Set, выполняемый в пределах массива BoundedArray.

4. Измените листинг 15.1 таким образом, чтобы класс String включал перегруженный оператор вывода (>>).

5. Жучки: найдите ошибки в этом коде:

   1: #include <iostream.h>

   2:

   3: class Animal;

   4:

   5: void setValue(Animal& , int);

   6:

   7:

   8: class Animal

   9: {

   10:   public:

   11:      int GetWeight()const { return itsWeight; }

   12:      int GetAge() const { return itsAge; }

   13:   private:

   14:      int itsWeight;

   15:      int itsAge;

   16: };

   17:

   18: void setValue(Animal& theAnimal, int theWeight)

   19: {

   20:    friend class Animal;

   21:    theAnimal.itsWeight = theWeight;

   22: }

   23:

   24: int main()

   25: {

   26:    Animal peppy;

   27:    setValue(peppy,5);

   28: }

6. Исправьте листинг, приведенный в упражнении 5, и откомпилируйте его.

7. Жучки: найдите ошибки в этом коде:

   1: #include<iostream.h>

   2:

   3: class Animal;

   4:

   5: void setValue(Animal& , int);

   6: void setValue(Animal&. ,int,int);

   7:

   8: class Animal

   9: {

   10:   friend void setValue(Animal& ,int);

   11:   private:

   12:      int itsWeight;

   13:      int itsAge;

   14: };

   15:

   16: void setValue(Animal& theAnimal, int theWeight)

   17: {

   18:    theAnimal.itsWeight = theWeight;

   19: }

   20:

   21:

   22: void setValue(Animal& theAnimal, int theWeight, int theAge)

   23: {

   24:    theAnimal.itsWeight = theWeight;

   25:    theAnimal.itsAge = theAge;

   26: }

   27:

   28: int main()

   29: {

   30:    Animal peppy;

   31:    setValue(peppy,5);

   32:    setValue(peppy, 7, 9);

   33: }

8. Исправьте листинг, приведенный в упражнении 7, и откомпилируйте его.

День 16-й. Потоки

Ранее для вывода на экран и считывания с клавиатуры мы использовали объекты cout и cin, не понимая до конца принципов их работы. Сегодня вы узнаете:

• Что такое потоки ввода-вывода и как они используются

• Как с помощью потоков управлять вводом и выводом данных

• Как с помощью потоков записывать информацию в файл и затем считывать ее

Знакомство с потоками

Язык программирования C++ специально не определяет, каким образом данные выводятся на экран или в файл либо как они считываются программой. Тем не менее эти особенности являются важной частью работы программиста, поэтому стандартная библиотека C++ включает библиотеку iostream, упрощающую ввод-вывод (I/O).

Благодаря выделению операций ввода-вывода в отдельную библиотеку упрощается создание аппаратно независимого языка разработки программ для разных платформ. Это позволяет создать программу на C++ для компьютеров PC, а затем откомпилировать ее для рабочей станции Sun. Разработчики снабдили компилятор библиотеками для всех случаев. Так, по крайней мере, должно быть теоретически.

Примечание:Библиотека — это набор файлов OBJ, которые можно подключать к программе для получения дополнительных функциональных возможностей. Это наиболее распространенная форма многократного использования кода, и можно сказать, что она существует еще с тех пор, как первобытные программисты каменного века выбивали первые нули и единицы на стенах своих пещер.

Инкапсуляция

Классы iostream рассматривают информацию, выводимую программой на экран, как побитовый поток данных. Если данные выводятся в файл или на экран, то источник потока, как правило, содержится в программе. Если же поток направлен в противоположную сторону, данные могут поступать с клавиатуры или файла на диске. В этом случае они заносятся в переменные.

Одна из основных целей использования потоков состоит в инкапсуляции процедуры обмена данными с диском или дисплеем компьютера. Сама программа работает только с потоками, которые реализуют эти процессы. Схематически эта идея проиллюстрирована на рис. 16.1.

Рис. 16.1. Инкапсуляция с помощью потоков

Буферизация

Запись на диск (и в меньшей степени вывод на экран) обходится очень дорого. Запись данных на диск и считывание их с диска требует довольно много времени, что может надолго заблокировать выполнение программы. Для решения этой проблемы потоки обеспечивают буферизацию. Данные сначала записываются в буфер потока, а после его наполнения вся информация разом записывается на диск.

Суть идеи проиллюстрирована на примере знакомого со школьной скамьи бака с в.одой (рис. 16.2). Вода заливается сверху, и бак постепенно наполняется, поскольку нижний вентиль закрыт.

Когда вода (данные) достигает верха, нижний вентиль автоматически открывается и вся вода выливается (рис. 16.3).

Как только бак опустеет, нижний вентиль закрывается, а верхний открывается вновь, и вода снова поступает в бак (рис. 16.4).

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

Рис. 16.2. Буфер наполняется данными, как закрытый бак — водой

Рис. 16.3. Открывается сливной вентиль, и вода (данные) сливается из бака

Рис. 16.4. Повторное наполнение бака

Рис. 16.5. Очистка буфера подобна экстренному сливу воды

Потоки и буферы

В C++ применяется объектно-ориентированный подход к реализации обмена данными с буферизированными потоками.

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

• Класс ios является базовым для классов потоков ввода-вывода. В качестве переменной-члена класса ios выступает объект streambuf.

• Классы istream и ostream являются производными от класса ios и отвечают соответственно за потоковый ввод и вывод данных.

• Класс iosteam является производным от классов istream и ostream и обеспечивает методы ввода-вывода для печати на экран.

• Классы fstream используются для ввода-вывода из файлов.

Стандартные объекты ввода-вывода

При запуске программы, включающей классы iostreams, создаются и инициируются четыре объекта.

Примечание:Библиотека класса iostream встроена в компилятор. Чтобы добавить в свою программу методы этого класса, достаточно в первых строках программы включить выражение #include<iostream>.

1 ... 103 104 105 106 107 108 109 110 111 ... 170
На этой странице вы можете бесплатно читать книгу Освой самостоятельно С++ за 21 день. - Джесс Либерти бесплатно.

Оставить комментарий