Мюррей Хилл - C++
- Название:C++
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Мюррей Хилл - C++ краткое содержание
С++ – это универсальный язык программирования, задуманный так, чтобы сделать программирование более приятным для серьезного программиста. За исключением второстепенных деталей С++ является надмножеством языка программирования C. Помимо возможностей, которые дает C, С++ предоставляет гибкие и эффективные средства определения новых типов. Используя определения новых типов, точно отвечающих концепциям приложения, программист может разделять разрабатываемую программу на легко поддающиеся контролю части. Такой метод построения программ часто называют абстракцией данных. Информация о типах содержится в некоторых объектах типов, определенных пользователем. Такие объекты просты и надежны в использовании в тех ситуациях, когда их тип нельзя установить на стадии компиляции. Программирование с применением таких объектов часто называют объектно-ориентированным. При правильном использовании этот метод дает более короткие, проще понимаемые и легче контролируемые программы.
Ключевым понятием С++ является класс. Класс – это тип, определяемый пользователем. Классы обеспечивают сокрытие данных, гарантированную инициализацию данных, неявное преобразование типов для типов, определенных пользователем, динамическое задание типа, контролируемое пользователем управление памятью и механизмы перегрузки операций. С++ предоставляет гораздо лучшие, чем в C, средства выражения модульности программы и проверки типов. В языке есть также усовершенствования, не связанные непосредственно с классами, включающие в себя символические константы, inline-подстановку функций, параметры функции по умолчанию, перегруженные имена функций, операции управления свободной памятью и ссылочный тип. В С++ сохранены возможности языка C по работе с основными объектами аппаратного обеспечения (биты, байты, слова, адреса и т.п.). Это позволяет весьма эффективно реализовывать типы, определяемые пользователем.
С++ и его стандартные библиотеки спроектированы так, чтобы обеспечивать переносимость. Имеющаяся на текущий момент реализация языка будет идти в большинстве систем, поддерживающих C. Из С++ программ можно использовать C библиотеки, и с С++ можно использовать большую часть инструментальных средств, поддерживающих программирование на C.
Эта книга предназначена главным образом для того, чтобы помочь серьезным программистам изучить язык и применять его в нетривиальных проектах. В ней дано полное описание С++, много примеров и еще больше фрагментов программ.
C++ - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Программа, состоящая из нескольких раздельно компилирумых файлов, должна быть согласованной в смысле использования имен и типов, точно так же, как и программа, состоящая из оного исходного файла. В принципе, это может обеспечить и копоновщик*. Компоновщик – это программа, стыкующая отдельно скомпилированные части вместе. Компоновщик часто (путая) нзывают загрузчиком. В UNIX'е компоновщик называется ld. Однко компоновщики, имеющиеся в большинстве систем, обеспечивают очень слабую поддержку проверки согласованности.
– * или линкер. (прим. перев.)
Программист может скомпенсировать недостаток поддержки со стороны компоновщика, предоставив дополнительную информцию о типах (описания). После этого согласованность программы обеспечивается проверкой согласованности описаний, которые
находятся в отдельно компилируемых частях. Средства, которые это обеспечивают, в вашей системе будут. С++ разработан так, чтобы способствовать такой явной компоновке*.
– * C разработан так, чтобы в большинстве случаев позвлять осуществлять неявную компоновку. Применение C, однако, возросло неимоверно, поэтому случаи, когда можно использовать неявную линковку, сейчас составляют незначительное меньшинтво. (прим. автора)
4.2 Компоновка
Если не указано иное, то имя, не являющееся локальным для функции или класса, в каждой части программы, компилирумой отдельно, должно относиться к одному и тому же типу, знчению, функции или объекту. То есть, в программе может быть только один нелокальный тип, значение, функция или объект с этим именем. Рассмотрим, например, два файла:
// file1.c: int a = 1; int f() (* /* что-то делает */ *)
// file2.c: extern int a; int f(); void g() (* a = f(); *)
a и f(), используемые g() в файле file2.c,– те же, что определены в файле file1.c. Ключевое слово extern (внешнее) указывает, что описание a в file2.c является (только) описнием, а не определением. Если бы a инициализировалось, extern было бы просто проигнорировано, поскольку описание с иницилизацией всегда является определением. Объект в программе должен определяться только один раз. Описываться он может много раз, но типы должны точно согласовываться. Например:
// file1.c: int a = 1; int b = 1; extern int c;
// file2.c: int a; extern double b; extern int c;
Здесь три ошибки: a определено дважды (int a; является определением, которое означает int a=0;), b описано дважды с разными типами, а c описано дважды, но не определено. Эти вды ошибок не могут быть обнаружены компилятором, который за один раз видит только один файл. Компоновщик, однако, их онаруживает.
Следующая программа не является С++ программой (хотя C программой является):
// file1.c: int a; int f() (* return a; *)
// file2.c: int a; int g() (* return f(); *)
Во-первых, file2.c не С++, потому что f() не была описана, и поэтому компилятор будет недоволен. Во-вторых, (когда file2.c фиксирован) программа не будет скомпонована, посколку a определено дважды.
Имя можно сделать локальным в файле, описав его static. Например:
// file1.c: static int a = 6; static int f() (* /* ... */ *)
// file2.c: static int a = 7; static int f() (* /* ... */ *)
Поскольку каждое a и f описано как static, получающаяся в результате программа является правильной. В каждом файле своя a и своя f().
Когда переменные и функции явно описаны как static, часть программы легче понять (вам не надо никуда больше залядывать). Использование static для функций может, помимо этого, выгодно влиять на расходы по вызову функции, поскольку дает оптимизирующему компилятору более простую работу.
Рассмотрим два файла:
// file1.c: const int a = 6; inline int f() (* /* ... */ *) struct s (* int a,b; *)
// file1.c: const int a = 7; inline int f() (* /* ... */ *) struct s (* int a,b; *)
Раз правило «ровно одно определение» применяется к контантам, inline-функциям и определениям функций так же, как оно применяется к функциям и переменным, то file1.c и file2.c не могут быть частями одной С++ программы. Но если это так, то как же два файла могут использовать одни и те же типы и константы? Коротко, ответ таков: типы, константы и т.п. могут определяться столько раз, сколько нужно, при условии, что они определяются одинаково. Полный ответ несколько более сложен (это объясняется в следующем разделе).
4.3 Заголовочные Файлы
Типы во всех описаниях одного и того же объекта должны быть согласованными. Один из способов это достичь мог бы сотоять в обеспечении средств проверки типов в компоновщике, но большинство компоновщиков – образца 1950-х, и их нельзя измнить по практическим соображениям*. Другой подход состоит в обеспечении того, что исходный текст, как он передается на рассмотрение компилятору, или согласован, или содержит инфомацию, которая позволяет компилятору обнаружить несогласованости. Один несовершенный, но простой способ достичь согласванности состоит во включении заголовочных файлов, содержащих интерфейсную информацию, в исходные файлы, в которых содежится исполняемый код и/или определения данных.
– * Легко изменить один компоновщик, но сделав это и напсав программу, которая зависит от усовершенствований, как вы будете переносить эту программу в другое место? (прим. автра)
Механизм включения с помощью #include – это чрезвычайно простое средство обработки текста для сборки кусков исходной программы в одну единицу (файл) для ее компиляции. Директива
#include «to_be_included»
замещает строку, в которой встретилось #include, содежимым файла «to_be_included». Его содержимым должен быть иходный текст на С++, поскольку дальше его будет читать комплятор. Часто включение обрабатывается отдельной программой, называемой C препроцессором, которую команда CC вызывает для преобразования исходного файла, который дал программист, в файл без директив включения перед тем, как начать собственно компиляцию. В другом варианте эти директивы обрабатывает итерфейсная система компилятора по мере того, как они встречются в исходном тексте. Если программист хочет посмотреть на результат директив включения, можно воспользоваться командой
CC -E file.c
для препроцессирования файла file.c точно также, как это сделала бы CC перед запуском собственно компилятора. Для включения файлов из стандартной директории включения вместо кавычек используются угловые скобки « и ». Например:
#include «stream.h» //из стандартной директории включения #define «myheader.h» // из текущей директории
Использование «» имеет то преимущество, что в программу фактическое имя директории включения не встраивается (как правило, сначала просматривается /usr/include/CC, а потом usr /include). К сожалению, пробелы в директиве include сущесвенны:
#include « stream.h » // не найдет «stream.h»
Может показаться, что перекомпилировать файл заново кадый раз, когда он куда-либо включается, расточительно, но время компиляции такого файла обычно слабо отличается от врмени, которое необходимо для чтения его некоторой заранее окомпилированной формы. Причина в том, что текст программы яляется довольно компактным представлением программы, и в том, что включаемые файлы обычно содержат только описания и не сдержат программ, требующих от компилятора значительного анлиза.
Читать дальшеИнтервал:
Закладка: