будут иметь нечто общее; заведите (почти) универсальный
базовый класс, и разработайте его наиболее тщательно.
[2] Когда вы определяете класс, который не реализует
некоторый математический объект, вроде матрицы или
комплексного числа, или тип низкого уровня, вроде связанного
списка, то:
[a] Не используйте глобальные данные.
[b] Не используйте глобальные функции (не члены).
[c] Не используйте открытые данные-члены.
[d] Не используйте друзей, кроме как чтобы избежать [a], [b]
или [c].
[e] Не обращайтесь к данным-членам или другим объектам
непосредственно.
[f] Не помещайте в класс "поле типа"; используйте виртуальные
функции.
[g] Не используйте inline-функции, кроме как средство
существенной оптимизации.
Замечания для программистов на С
Чем лучше кто-нибудь знает C, тем труднее окажется избежать
писания на C++ в стиле C, теряя, тем самым, некоторые возможные
выгоды C++. Поэтому проглядите, пожалуйста, раздел "Отличия от C" в
справочном руководстве (#с.15). Там указывается на области, в
которых C++ позволяет делать что-то лучше, чем C. Макросы (#define)
в C++ почти никогда не бывают необходимы; чтобы определять
провозглашаемые константы, используйте const (#2.4.6) или enum
(#2.4.7), и inline (#1.12) - чтобы избежать лишних расходов на
вызов функции. Старайтесь описывать все функции и типы всех
параметров - есть очень мало веских причин этого не делать.
Аналогично, практически нет причин описывать локальную переменную
не инициализируя ее, поскольку описание может появляться везде, где
может стоять оператор, - не описывайте переменную, пока она вам не
нужна. Не используйте malloc() - операция new (#3.2.6) делает ту же
работу лучше. Многие объединения не нуждаются в имени - используйте
безымянные объединения (#2.5.2).
* Глава 1 *
Турне по C++
Единственный способ изучать новый язык
программирования - писать на нем программы.
- Брайэн Керниган
Эта глава представляет собой краткий обзор основных черт языка
программирования C++. Сначала приводится программа на C++, затем
показано, как ее откомпилировать и запустить, и как такая программа
может выводить выходные данные и считывать входные. В первой трети
этой главы после введения описаны наиболее обычные черты C++:
основные типы, описания, выражения, операторы, функции и структура
программы. Оставшаяся часть главы посвящена возможностям C++ по
определению новых типов, скрытию данных, операциям, определяемым
пользователем, и иерархии определяемых пользователем типов.
1.1 Введение
Это турне проведет вас через ряд программ и частей программ на
C++. К концу у вас должно сложиться общее представление об основных
особенностях C++, и будет достаточно информации, чтобы писать
простые программы. Для точного и полного объяснения понятий,
затронутых даже в самом маленьком законченном примере,
потребовалось бы несколько страниц определений. Чтобы не превращать
эту главу в описание или в обсуждение общих понятий, примеры
снабжены только самыми короткими определениями используемых
терминов. Термины рассматриваются позже, когда будет больше
примеров, способствующих обсуждению.
1.1.1 Вывод
Прежде всего, давайте напишем программу, выводящую строку
выдачи:
#include
main()
{
cout << "Hello, world\n";
}
Строка #include сообщает компилятору, чтобы он включил
стандартные возможности потока ввода и вывода, находящиеся в файле
stream.h. Без этих описаний выражеине cout << "Hello, world\n" не
имело бы смысла. Операция << ("поместить в"*) пишет свой первый
аргумент во второй (в данном случае, строку "Hello, world\n" в
____________________
* Программирующим на C << известно как операция сдвига влево для
целых. Такое использование << не утеряно; просто в дальнейшем <<
было определено для случая, когда его левый операнд является
потоком вывода. Как это делается, описано в #1.8. (прим. автора)
- стр 20 -
стандартный поток вывода cout). Строка - это последовательность
символов, заключенная в двойные кавычки. В строке символ обратной
косой \, за которым следует другой символ, обозначает один
специальный символ; в данном случае, \n является символом новой
строки. Таким образом выводимые символы состоят из Hello, world и
перевода строки.
Остальная часть программы
main() { ... }
определяет функцию, названную main. Каждая программа должна
содержать функцию с именем main, и работа программы начинается с
выполнения этой функции.
1.1.2 Компиляция
Откуда появились выходной поток cout и код, реализующий операцию
вывода <<<< были описаны в stream.h, то есть, были
указаны их типы, но не было дано никаких подробностей относительно
их реализации. В стандартной библиотеке содержится спецификация
пространства и инициализирующий код для cout и <<< "inches";
cin >> inch;
cout << inch;
cout << " in = ";
cout << inch*2.54;
cout << " cm\n";
}
Первая строка функции main() описывает целую переменную inch. Ее
значение считывается с помощью операции >> ("взять из") над
стандартным потоком ввода cin. Описания cin и >>, конечно же,
находятся в . После ее запуска ваш терминал может
выглядеть примерно так:
$ a.out
inches=12
12 in = 30.48 cm
$
В этом примере на каждую команду вывода приходится один оператор;
это слишком длинно. Операцию вывода << можно применять к ее
собственному результату, так что последние четыре команды вывода
можно было записать одним оператором:
cout << inch << " in = " << inch*2.54 << " cm\n";
- стр 22 -
В последующих разделах ввод и вывод будут описаны гораздо более
подробно. Вся эта глава фактически может рассматриваться как
объяснение того, как можно написать предыдущие программы на языке,
который не обеспечивает операции ввода-вывода. На самом деле,
приведенные выше программы написаны на C++, "расширенном"
операциями ввода-вывода посредством использования библиотек и
включения файлов с помощью #include. Другими словами, язык C++ в
том виде, в котором он описан в справочном руководстве, не
определяет средств ввода-вывода; вместо этого исключительно с
помощью средств, доступных любому программисту, определены операции
<< и >>.
1.2 Комментарии
Часто бывает полезно вставлять в программу текст, который
предназначается в качестве комментария только для читающего
программу человека и игнорируется компилятором в программе. В C++
это можно сделать одним из двух способов.
Символы /* начинают комментарий, заканчивающийся символами */.
Вся эта последовательность символов эквивалентна символу пропуска
(например, символу пробела). Это наиболее полезно для многострочных
комментариев и изъятия частей программы при редактировании, однако
следует помнить, что комментарии /* */ не могут быть вложенными.
Символы // начинают комментарий, который заканчивается в конце
строки, на которой они появились. Опять, вся последовательность
символов эквивалентна пропуску. Этот способ наиболее полезен для
коротких комментариев. Символы // можно использовать для того,
чтобы закомментировать символы /* или */, а символами /* можно
закомментировать //.
1.3 Типы и Описания
Каждое имя и каждое выражение имеет тип, определяющий операции,
которые могут над ними производиться. Например, описание
int inch;
определяет, что inch имеет тип int, то есть, inch является целой
переменной.
Описание - это оператор, который вводит имя в программе. Описание
задает тип этого имени. Тип определяет правильное использование
имени или выражения. Для целых определены такие операции, как +, -,
* и /. После того, как включен файл stream.h, объект типа int может
также быть вторым операндом <<, когда первый операнд ostream.
Тип объекта определяет не только то, какие операции могут к нему
применяться, но и смысл этих операций. Например, оператор
cout << inch << " in = " << inch*2.54 << " cm\n";
правильно обрабатывает четыре входных значения различным образом.
Строки печатаются буквально, тогда как целое inch и значение с
плавающей точкой inch*2.54 преобразуются из их внутреннего
представлениия в подходящее для человеческого глаза символьное
представление.
- стр 23 -
В C++ есть несколько основных типов и несколько способов
создавать новые. Простейшие виды типов C++ описываются в следующих
разделах, а более интересные оставлены на потом.
1.3.1 Основные Типы
Основные типы, наиболее непосредственно отвечающие средствам
аппаратного обеспечения, такие:
char short int long float double
Первые четыре типа используются для представления целых, последние
два - для представления чисел с плавающей точкой. Переменная типа
char имеет размер, естественный для хранения символа на данной
машине (обычно, байт), а переменная типа int имеет размер,
соответствующий целой арифметике на данной машине (обычно, слово).
Диапазон целых чисел, которые могут быть представлены типом,
зависит от его размера. В C++ размеры измеряются в единицах размера
данных типа char, поэтому char по определению имеет размер единица.
Соотношение между основными типами можно записать так:
1 = sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
sizeof(float) <= sizeof(double)
В целом, предполагать что-либо еще относительно основных типов
неразумно. В частности, то, что целое достаточно для хранения
указателя, верно не для всех машин.
К основному типу можно применять прилагательное const. Это дает
тип, имеющий те же свойства, что и исходный тип, за исключением
того, что значение переменных типа const не может изменяться после
инициалиизации.
const float pi = 3.14;
const char plus = '+';
Символ, заключенный в одинарные кавычки, является символьной