Мюррей Хилл - C++

Тут можно читать онлайн Мюррей Хилл - C++ - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    C++
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    3.9/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Мюррей Хилл - C++ краткое содержание

C++ - описание и краткое содержание, автор Мюррей Хилл, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

С++ – это универсальный язык программирования, задуманный так, чтобы сделать программирование более приятным для серьезного программиста. За исключением второстепенных деталей С++ является надмножеством языка программирования C. Помимо возможностей, которые дает C, С++ предоставляет гибкие и эффективные средства определения новых типов. Используя определения новых типов, точно отвечающих концепциям приложения, программист может разделять разрабатываемую программу на легко поддающиеся контролю части. Такой метод построения программ часто называют абстракцией данных. Информация о типах содержится в некоторых объектах типов, определенных пользователем. Такие объекты просты и надежны в использовании в тех ситуациях, когда их тип нельзя установить на стадии компиляции. Программирование с применением таких объектов часто называют объектно-ориентированным. При правильном использовании этот метод дает более короткие, проще понимаемые и легче контролируемые программы.

Ключевым понятием С++ является класс. Класс – это тип, определяемый пользователем. Классы обеспечивают сокрытие данных, гарантированную инициализацию данных, неявное преобразование типов для типов, определенных пользователем, динамическое задание типа, контролируемое пользователем управление памятью и механизмы перегрузки операций. С++ предоставляет гораздо лучшие, чем в C, средства выражения модульности программы и проверки типов. В языке есть также усовершенствования, не связанные непосредственно с классами, включающие в себя символические константы, inline-подстановку функций, параметры функции по умолчанию, перегруженные имена функций, операции управления свободной памятью и ссылочный тип. В С++ сохранены возможности языка C по работе с основными объектами аппаратного обеспечения (биты, байты, слова, адреса и т.п.). Это позволяет весьма эффективно реализовывать типы, определяемые пользователем.

С++ и его стандартные библиотеки спроектированы так, чтобы обеспечивать переносимость. Имеющаяся на текущий момент реализация языка будет идти в большинстве систем, поддерживающих C. Из С++ программ можно использовать C библиотеки, и с С++ можно использовать большую часть инструментальных средств, поддерживающих программирование на C.

Эта книга предназначена главным образом для того, чтобы помочь серьезным программистам изучить язык и применять его в нетривиальных проектах. В ней дано полное описание С++, много примеров и еще больше фрагментов программ.

C++ - читать онлайн бесплатно полную версию (весь текст целиком)

C++ - читать книгу онлайн бесплатно, автор Мюррей Хилл
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Для типа ассоциативного массива assoc мы не определили итератор. Это можно сделать, определив класс assoc_iterator, работа которого состоит в том, чтобы в определенном порядке поставлять элементы из assoc. Итератору нужен доступ к даным, которые хранятся в assoc, поэтому он сделан другом:

class assoc (* friend class assoc_iterator; pair* vec; int max; int free; public: assoc(int); int amp; operator[](char*); *);

Итератор определяется как

class assoc_iterator(* assoc* cs; // текущий массив assoc int i; // текущий индекс public: assoc_iterator(assoc amp; s) (* cs = amp;s; i = 0; *) pair* operator()() (* return (i«cs-»free)? amp;cs-»vec[i++] : 0; *) *);

Надо инициализировать assoc_iterator для массива assoc, после чего он будет возвращать указатель на новую pair из этого массива всякий раз, когда его будут активизировать опрацией (). По достижении конца массива он возвращает 0:

main() // считает вхождения каждого слова во вводе (* const MAX = 256; // больше самого большого слова char buf[MAX]; assoc vec(512); while (cin»»buf) vec[buf]++; assoc_iterator next(vec); pair* p; while ( p = next() ) cout «„ p-“name „„ ": " «« p-“val «« «\n“; *)

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

Конечно, такое применение объектов для представления итераторов никак особенно с перегрузкой операций не связано. Многие любят использовать итераторы с такими операциями, как first(), next() и last() (первый, следующий и последний).

6.9 Класс String

Вот довольно реалистичный пример класса строк string. В нем производится учет ссылок на строку с целью минимизировать копирование и в качестве констант применяются стандартные символьные строки С++.

#include «stream.h» #include «string.h»

class string (* struct srep (* char* s; // указатель на данные int n; // счетчик ссылок *); srep *p;

public: string(char *); // string x = «abc» string(); // string x; string(string amp;); // string x = string ... string amp; operator=(char *); string amp; operator=(string amp;); ~string(); char amp; operator[](int i);

friend ostream amp; operator«„(ostream amp;, string amp;); friend istream amp; operator“»(istream amp;, string amp;);

friend int operator==(string amp; x, char* s) (*return strcmp(x.p-»s, s) == 0; *)

friend int operator==(string amp; x, string amp; y) (*return strcmp(x.p-»s, y.p-»s) == 0; *)

friend int operator!=(string amp; x, char* s) (*return strcmp(x.p-»s, s) != 0; *)

friend int operator!=(string amp; x, string amp; y) (*return strcmp(x.p-»s, y.p-»s) != 0; *)

*);

Конструкторы и деструкторы просты (как обычно):

string::string() (* p = new srep; p-»s = 0; p-»n = 1; *)

string::string(char* s) (* p = new srep; p-»s = new char[ strlen(s)+1 ]; strcpy(p-»s, s); p-»n = 1; *)

string::string(string amp; x) (* x.p-»n++; p = x.p; *)

string::~string() (* if (–p-»n == 0) (* delete p-»s; delete p; *) *)

Как обычно, операции присваивания очень похожи на контрукторы. Они должны обрабатывать очистку своего первого (лвого) операнда:

string amp; string::operator=(char* s) (* if (p-»n » 1) (* // разъединить себя p-»n–; p = new srep; *) else if (p-»n == 1) delete p-»s;

p-»s = new char[ strlen(s)+1 ]; strcpy(p-»s, s); p-»n = 1; return *this; *)

Благоразумно обеспечить, чтобы присваивание объекта смому себе работало правильно:

string amp; string::operator=(string amp; x) (* x.p-»n++; if (–p-»n == 0) (* delete p-»s; delete p; *) p = x.p; return *this; *)

Операция вывода задумана так, чтобы продемонстрировать применение учета ссылок. Она повторяет каждую вводимую строку (с помощью операции ««, которая определяется позднее):

ostream amp; operator«„(ostream amp; s, string amp; x) (* return s „„ x.p-“s „« « [“ «« x.p-“n «« «]\n“; *)

Операция ввода использует стандартную функцию ввода сивольной строки (#8.4.1).

istream amp; operator»»(istream amp; s, string amp; x) (* char buf[256]; s »» buf; x = buf; cout «„ "echo: " «« x «« «\n“; return s; *)

Для доступа к отдельным символам предоставлена операция индексирования. Осуществляется проверка индекса:

void error(char* p) (* cerr «„ p «« «\n“; exit(1); *)

char amp; string::operator[](int i) (* if (i«0 !! strlen(p-»s)«i) error(„индекс за границами“); return p-»s[i]; *)

Головная программа просто немного опробует действия над строками. Она читает слова со ввода в строки, а потом эти строки печатает. Она продолжает это делать до тех пор, пока не распознает строку done, которая завершает сохранение слов в строках, или пока не встретит конец файла. После этого она печатает строки в обратном порядке и завершается.

main() (* string x[100]; int n;

cout «„ „отсюда начнем\n“; for (n = 0; cin“»x[n]; n++) (* string y; if (n==100) error(«слишком много строк»); cout «„ (y = x[n]); if (y=="done") break; *) cout «« «отсюда мы пройдем обратно\n“;

for (int i=n-1; 0«=i; i–) cout «« x[i]; *)

6.10 Друзья и Члены

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

Рассмотрим простой класс X:

class X (* // ... X(int); int m(); friend int f(X amp;); *);

Внешне не видно никаких причин делать f(X amp;) другом дполнительно к члену X::m() (или наоборот), чтобы реализовать действия над классом X. Однако член X::m() можно вызывать только для «настоящего объекта», в то время как друг f() мжет вызываться для объекта, созданного с помощью неявного преобразования типа. Например:

void g() (* 1.m(); // ошибка f(1); // f(x(1)); *)

Поэтому операция, изменяющая состояние объекта, должна быть членом, а не другом. Для определяемых пользователем тпов операции, требующие в случае фундаментальных типов опранд lvalue (=, *=, ++, *= и т.д.), наиболее естественно оределяются как члены.

И наоборот, если нужно иметь неявное преобразование для всех операндов операции, то реализующая ее функция должна быть другом, а не членом. Это часто имеет место для функций, которые реализуют операции, не требующие при применении к фундаментальным типам lvalue в качестве операндов (+, -, !! и т.д.).

Если никакие преобразования типа не определены, то окзывается, что нет никаких существенных оснований в пользу члена, если есть друг, который получает ссылочный параметр, и наоборот. В некоторых случаях программист может предпочитать один синтаксис вызова другому. Например, оказывается, что большинство предпочитает для обращения матрицы m запись m.inv (). Конечно, если inv() действительно обращает матрицу m, а не просто возвращает новую матрицу, обратную m, ей следует быть членом.

При прочих равных условиях выбирайте, чтобы функция была членом: никто не знает, вдруг когда-нибудь кто-то определит операцию преобразования. Невозможно предсказать, потребуют ли будущие изменения изменять состояние объекта. Синтаксис вызва функции члена ясно указывает пользователю, что объект моно изменить; ссылочный параметр является далеко не столь очвидным. Кроме того, выражения в члене могут быть заметно короче выражений в друге. В функции друге надо использовать явный параметр, тогда как в члене можно использовать неявный this. Если только не применяется перегрузка, имена членов

обычно короче имен друзей.

6.11 Предостережение

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

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Мюррей Хилл читать все книги автора по порядку

Мюррей Хилл - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




C++ отзывы


Отзывы читателей о книге C++, автор: Мюррей Хилл. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x