C++ - Страустрап Бьярн, Хилл Мюррей

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

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

matrix operator+(matrix amp;, matrix amp;); (* matrix sum; for (int i=0; i«4; i++) for (int j=0; j«4; j++) sum.m[i][j] = arg1.m[i][j] + arg2.m[i][j]; return sum; *)

Эта operator+() обращается к операндам + через ссылки, но возвращает значение объекта. Возврат ссылки может оказатся более эффективным:

class matrix (* // ... friend matrix amp; operator+(matrix amp;, matrix amp;);

friend matrix amp; operator*(matrix amp;, matrix amp;); *);

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

6.6 Присваивание и инициализация

Рассмотрим очень простой класс строк string:

struct string (* char* p; int size; // размер вектора, на который указывает p

string(int sz) (* p = new char[size=sz]; *) ~string() (* delete p; *) *);

Строка – это структура данных, состоящая из вектора сиволов и длины этого вектора. Вектор создается конструктором и уничтожается деструктором. Однако, как показано в #5.10, это может привести к неприятностям. Например:

void f() (* string s1(10); string s2(20); s1 = s2; *)

будет размещать два вектора символов, а присваивание s1= s2 будет портить указатель на один из них и дублировать дргой. На выходе из f() для s1 и s2 будет вызываться деструктор и уничтожать один и тот же вектор с непредсказуемо разруштельными последствиями. Решение этой проблемы состоит в том, чтобы соответствующим образом определить присваивание объетов типа string:

struct string (* char* p; int size; // размер вектора, на который указывает p

string(int sz) (* p = new char[size=sz]; *) ~string() (* delete p; *) void operator=(string amp;) *);

void string::operator=(string amp; a) (* if (this == amp;a) return; // остерегаться s=s; delete p; p=new char[size=a.size]; strcpy(p,a.p); *)

Это определение string гарантирует,и что предыдущий прмер будет работать как предполагалось. Однако небольшое измнение f() приведет к появлению той же проблемы в новом облике:

void f() (* string s1(10); s2 = s1; *)

Теперь создается только одна строка, а уничтожается две. К неинициализированному объекту определяемая пользователем операция присваивания не применяется. Беглый взгляд на string::operator=() объясняет, почему было бы неразумно так делать: указатель p будет содержать неопределенное и совешенно случайное значение. Часто операция присваивания полагется на то, что ее аргументы инициализированы. Для такой инциализации, как здесь, это не так по определению. Следовательно, нужно определить похожую, но другую, функцию, чтобы обрабатывать инициализацию:

struct string (* char* p; int size; // размер вектора, на который указывает p

string(int sz) (* p = new char[size=sz]; *) ~string() (* delete p; *) void operator=(string amp;); string(string amp;); *);

void string::string(string amp; a) (* p=new char[size=a.size]; strcpy(p,a.p); *)

Для типа X инициализацию тем же типом X обрабатывает конструктор X(X amp;). Нельзя не подчеркнуть еще раз, что присвивание и инициализация – разные действия. Это особенно сщественно при описании деструктора. Если класс X имеет контруктор X(X amp;), выполняющий нетривиальную работу вроде освобождения памяти, то скорее всего потребуется полный комлект функций, чтобы полностью избежать побитового копирования объектов:

Перейти
Наш сайт автоматически запоминает страницу, где вы остановились, вы можете продолжить чтение в любой момент
Оставить комментарий