Мюррей Хилл - C++
- Название:C++
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Мюррей Хилл - C++ краткое содержание
С++ – это универсальный язык программирования, задуманный так, чтобы сделать программирование более приятным для серьезного программиста. За исключением второстепенных деталей С++ является надмножеством языка программирования C. Помимо возможностей, которые дает C, С++ предоставляет гибкие и эффективные средства определения новых типов. Используя определения новых типов, точно отвечающих концепциям приложения, программист может разделять разрабатываемую программу на легко поддающиеся контролю части. Такой метод построения программ часто называют абстракцией данных. Информация о типах содержится в некоторых объектах типов, определенных пользователем. Такие объекты просты и надежны в использовании в тех ситуациях, когда их тип нельзя установить на стадии компиляции. Программирование с применением таких объектов часто называют объектно-ориентированным. При правильном использовании этот метод дает более короткие, проще понимаемые и легче контролируемые программы.
Ключевым понятием С++ является класс. Класс – это тип, определяемый пользователем. Классы обеспечивают сокрытие данных, гарантированную инициализацию данных, неявное преобразование типов для типов, определенных пользователем, динамическое задание типа, контролируемое пользователем управление памятью и механизмы перегрузки операций. С++ предоставляет гораздо лучшие, чем в C, средства выражения модульности программы и проверки типов. В языке есть также усовершенствования, не связанные непосредственно с классами, включающие в себя символические константы, inline-подстановку функций, параметры функции по умолчанию, перегруженные имена функций, операции управления свободной памятью и ссылочный тип. В С++ сохранены возможности языка C по работе с основными объектами аппаратного обеспечения (биты, байты, слова, адреса и т.п.). Это позволяет весьма эффективно реализовывать типы, определяемые пользователем.
С++ и его стандартные библиотеки спроектированы так, чтобы обеспечивать переносимость. Имеющаяся на текущий момент реализация языка будет идти в большинстве систем, поддерживающих C. Из С++ программ можно использовать C библиотеки, и с С++ можно использовать большую часть инструментальных средств, поддерживающих программирование на C.
Эта книга предназначена главным образом для того, чтобы помочь серьезным программистам изучить язык и применять его в нетривиальных проектах. В ней дано полное описание С++, много примеров и еще больше фрагментов программ.
C++ - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Вот пример, в котором преобразование необходимо:
overload print(double), print(long);
void f(int a); (* print(a); *)
Здесь a может быть напечатано или как double, или как long. Неоднозначность разрешается явным преобразованием типа (или print(long(a)) или print(double(a))).
При этих правилах можно гарантировать, что когда эффетивность или точность вычислений для используемых типов сщественно различаются, будет использоваться простейший алгритм (функция). Например:
overload pow; int pow(int, int); double pow(double, double); // из «math.h» complex pow(double, complex); // из «complex.h» complex pow(complex, int); complex pow(complex, double); complex pow(complex, complex);
Процесс поиска подходящей функции игнорирует unsigned и const.
4.6.8 Незаданное Число Параметров
Для некоторых функций невозможно задать число и тип всех параметров, которые можно ожидать в вызове. Такую функцию описывают завершая список описаний параметров многоточием (...), что означает «и может быть, еще какие-то неописанные параметры». Например:
int printf(char* ...);
Это задает, что в вызове printf должен быть по меньшей мере один параметр, char*, а остальные могут быть, а могут и не быть. Например:
printf(«Hello, world\n»); printf(«Мое имя %s %s\n», first_name, second_name); printf(«%d + %d = %d\n»,2,3,5);
Такая функция полагается на информацию, которая недотупна компилятору при интерпретации ее списка параметров. В случае printf() первым параметром является строка формата, содержащая специальные последовательности символов, позволящие printf() правильно обрабатывать остальные параметры. %s означает «жди параметра char*», а %d означает «жди параметра int». Однако, компилятор этого не знает, поэтому он не может убедиться в том, что ожидаемые параметры имеют соответствущий тип. Например: printf(«Мое имя %s %s\n»,2);
откомпилируется и в лучшем случае приведет к какой-нбудь странного вида выдаче. Очевиднще хуже, каждый вызов функции с автоматическим объектом класса включает по меньшей мере один вызов программ выделения и освобождения свободной памяти. Это сделало бы также невозможным реализацию inline-функций членов, которые обращаются к данным закрытой части. Более того, такое изменение сделает невозможным совместную компоновку C и С++ программ (поскольку C компилятор обрабатывает struct не так, как это будет делать С++ компилятор). Для С++ это было сочтено неприемлемым.
5.3.2 Законченный Класс
Программирование без сокрытия данных (с применением структур) требует меньшей продуманности, чем программирование со сокрытием данных (с использованием классов). Структуру можно определить не слишком задумываясь о том, как ее предплагается использовать. А когда определяется класс, все внимние сосредотачивается на обеспечении нового типа полным мнжеством операций; это важное смещение акцента. Время, потраченное на разработку нового типа, обычно многократно окупается при разработке и тестировании программы.
Вот пример законченного типа intset, который реализует понятие «множество целых»:
class intset (* int cursize, maxsize; int *x; public: intset(int m, int n); // самое большее, m int'ов в 1..n ~intset();
int member(int t); // является ли t элементом? void insert(int t); // добавить "t" в множество
void iterate(int amp; i) (* i = 0; *) int ok(int amp; i) (* return i«cursize; *) int next(int amp; i) (* return x[i++]; *) *);
Чтобы протестировать этот класс, можно создать и распчатать множество случайных целых чисел. Такое множество могло бы быть результатом розыгрыша лотереи. Это простое множество можно также использовать для проверки последовательности цлых на повторы. Но для большинства приложений тип множество должен быть немного более проработанным. Как всегда, возможны ошибки:
#include «stream.h»
void error(char* s) (* cerr «„ "set: " «« s «« «\n“; exit(1); *)
Класс intset используется в main(), которая предполагает два целых параметра. Первый параметр задает число случайных чисел, которые нужно сгенерировать. Второй параметр указывает диапазон, в котором должны лежать случайные целые:
main(int argc, char* argv[]) (* if (argc != 3) error(«ожидается два параметра»); int count = 0; int m = atoi(argv[1]); // число элементов множества int n = atoi(argv[2]); // в диапазоне 1..n intset s(m,n);
while (count«m) (* int t = randint(n);
if (s.member(t)==0) (* s.insert(t); count++; *) *)
print_in_order( amp;s); *)
В программе, для которой требуется два параметра, счечик числа параметров, argc, должен равняться трем, потому что имя программы всегда передается как argv[0]. Функция
extern int atoi(char*);
функция atoi() это стандартная библиотечная функция для преобразования представления целого в виде строки в его внуреннюю (двоичную) форму. Случайные числа генерируются с пмощью стандартной функции rand():
extern int rand(); // Не очень случайные, будьте осторожны
int randint(int u) // в диапазоне 1..u (* int r = rand(); if (r « 0) r = -r; return 1 + r%u ; *)
Подробности реализации класса должны представлять для пользователя весьма незначительный интерес, но здесь в любом случае будут функции члены. Конструктор выделяет целый вектор заданного максимального размера множества, а деструктор освбождает его:
intset::intset(int m, int n)//самое большее,m int'ов в 1..n (* if (m«1 !! n„m) error(«недопустимый размер intset“); cursize = 0; maxsize = m; x = new int[maxsize]; *)
intset::~intset() (* delete x; *)
Целые числа вставляются, поэтому они хранятся в возратающем порядке:
void intset::insert(int t) (* if (++cursize » maxsize) error(«слишком много элементов»); int i = cursize-1; x[i] = t;
while (i»0 amp; amp; x[i-1]»x[i]) (* int t = x[i]; // переставить x[i] и [i-1] x[i] = x[i-1]; x[i-1] = t; i–; *) *)
Для нахождения членов используется просто двоичный писк:
int intset::member(int t) // двоичный поиск (* int l = 0; int u = cursize-1;
while (l «= u) (* int m = (l+u)/2; if (t „ x[m]) u = m-1; else if (t “ x[m]) l = m+1; else return 1; // найдено *) return 0; // не найдено *)
И, наконец, нам нужно обеспечить множество операций, чтобы пользователь мог осуществлять цикл по множеству в нектором порядке, поскольку представление intset от пользователя скрыто. Множество внутренней упорядоченности не имеет, поэтму мы не можем просто дать возможность обращаться к вектору (завтра я, наверное, реализую intset по-другому, в виде свзанного списка).
Дается три функции: iterate() для инициализации итерции, ok() для проверки, есть ли следующий элемент, и next() для того, чтобы взять следующий элемент:
class intset (* // ... void iterate(int amp; i) (* i = 0; *) int ok(int amp; i) (* return i«cursize; *) int next(int amp; i) (* return x[i++]; *) *);
Чтобы дать возможность этим трем операциям работать соместно и чтобы запомнить, куда дошел цикл, пользователь дожен дать целый параметр. Поскольку элементы хранятся в отсотированном списке, их реализация тривиальна. Теперь можно определить функцию печати по порядку print_in_order:
void print_in_order(intset* set) (* int var; set-»iterate(var); while (set-»ok(var)) cout «„ set-“next(var) „« «\n“; *)
Другой способ задать итератор приводится в #6.8.
5.4 Друзья и Объединения
В это разделе описываются еще некоторые особенности, ксающиеся классов. Показано, как предоставить функции не члену доступ к закрытым членам. Описывается, как разрешать конфлиты имен членов, как можно делать вложенные описания классов, и как избежать нежелательной вложенности. Обсуждается также, как объекты класса могут совместно использовать члены данные, и как использовать указатели на члены. Наконец, приводится пример, показывающий, как построить дискриминирующее (экононое) объединение.
Читать дальшеИнтервал:
Закладка: