» » » » Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

На нашем литературном портале можно бесплатно читать книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп, Бьёрн Страуструп . Жанр: Программирование. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале litmir.org.
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Название: Программирование. Принципы и практика использования C++ Исправленное издание
Дата добавления: 22 август 2024
Количество просмотров: 98
Читать онлайн

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту readbookfedya@gmail.com для удаления материала

Программирование. Принципы и практика использования C++ Исправленное издание читать книгу онлайн

Программирование. Принципы и практика использования C++ Исправленное издание - читать бесплатно онлайн , автор Бьёрн Страуструп

Специальное издание самой читаемой и содержащей наиболее достоверные сведения книги по C++. Книга написана Бьярне Страуструпом — автором языка программирования C++ — и является каноническим изложением возможностей этого языка.
Помимо подробного описания собственно языка, на страницах книги вы найдете доказавшие свою эффективность подходы к решению разнообразных задач проектирования и программирования. Многочисленные примеры демонстрируют как хороший стиль программирования на С-совместимом ядре C++, так и современный -ориентированный подход к созданию программных продуктов. Третье издание бестселлера было существенно переработано автором. Результатом этой переработки стала большая доступность книги для новичков. В то же время, текст обогатился сведениями и методиками программирования, которые могут оказаться полезными даже для многоопытных специалистов по C++. Не обойдены вниманием и нововведения языка: стандартная библиотека шаблонов (STL), пространства имен (namespaces), механизм идентификации типов во время выполнения (RTTI), явные приведения типов (cast-операторы) и другие.
Настоящее специальное издание отличается от третьего добавлением двух новых приложений (посвященных локализации и безопасной обработке исключений средствами стандартной библиотеки), довольно многочисленными уточнениями в остальном тексте, а также исправлением множества опечаток.
Книга адресована программистам, использующим в своей повседневной работе C++. Она также будет полезна преподавателям, студентам и всем, кто хочет ознакомиться с описанием языка «из первых рук».

1 ... 96 97 98 99 100 ... 337 ВПЕРЕД
Перейти на страницу:
ведая того, обязательно воспользуется некорректным значением и получит сообщение об ошибке на этапе выполнения программы или — что еще хуже — получит неверные результаты. Все это лишь вопрос времени.

Такие размышления приводят к выводу, что представление типа Date, за исключением открытых функций-членов, должно быть недоступным для пользователей. Итак, получаем первое сокращение.

// простой типа Date (управление доступом)

class Date {

  int y, m, d; // год, месяц, день

public:

  Date(int y, int m, int d); // проверка и инициализация даты

  void add_day(int n);       // увеличение объекта типа Date на n дней

  int month() { return m; }

  int day() { return d; }

  int year() { return y; }

};

Этот класс можно использовать следующим образом:

Date birthday(1970, 12, 30);      // OK

birthday.m = 14;                  // ошибка: Date::m — закрытый член

cout << birthday.month() << endl; // доступ к переменной m

 

 Понятие “правильный объект типа Date” — важная разновидность идеи о корректном значении. Мы пытаемся разработать наши типы так, чтобы их значения гарантированно были корректными; иначе говоря, скрываем представление, предусматриваем конструктор, создающий только корректные объекты, и разрабатываем все функции-члены так, чтобы они получали и возвращали только корректные значения. Значение объекта часто называют состоянием (state), а корректное значение — корректным состоянием объекта.

В качестве альтернативы можно проверять корректность объекта при каждой попытке его использования или просто надеяться на то, что никто никогда не создаст ни одного некорректного значения. Опыт показывает, что такие надежды могут привести к “очень хорошим” программам. Однако создание таких программ, которые иногда выдают ошибочные результаты, а порой вообще приводят к аварийному отказу, не принесет вам профессионального признания. Мы предпочитаем писать программы, корректность которых можно продемонстрировать.

 

 Правило, регламентирующее смысл корректного значения, называют инвариантом (invariant). Инвариант для класса Date (“Объект класса Date должен представлять дату в прошлом, настоящем и будущем времени”) необычайно трудно сформулировать точно: вспомните о високосных годах, григорианском календаре, часовых поясах и т.п. Однако для простых и реалистичных ситуаций можно написать класс Date. Например, если мы инициализируем интернет-протоколы, нас не должны беспокоить ни григорианский, ни юлианский календари, ни календарь племени майя. Если мы не можем придумать хороший инвариант, то, вероятно, имеют место простые данные. В таких случаях следует использовать обычные структуры struct.

9.4.4. Определение функций-членов

До сих пор мы смотрели на класс Date с точки зрения разработчика интерфейса и пользователя. Однако рано или поздно нам придется реализовать его функции-члены. Во-первых, выделим подмножество класса Date, чтобы согласовать его с общепринятым стилем организации открытого интерфейса.

// простой класс Date (детали реализации будут рассмотрены позднее)

class Date {

public:

  Date(int y, int m, int d); // проверка и инициализация даты

  void add_day(int n);       // увеличивает объект класса Date на n дней

  int month();

  // ...

private:

  int y, m, d;               // лет, месяцев, дней

};

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

Определяя члены за пределами класса, мы должны указать, какому классу они принадлежат. Для этого используется обозначение имя_класса::имя_члена.

Date::Date(int yy, int mm, int dd)// конструктор

     :y(yy), m(mm), d(dd)         // примечание: инициализация члена

{

}

void Date::add_day(int n)

{

  // ...

}

int month()  // Ой: мы забыли про класс Date::

{

   return m; // не функция-член, к переменной m доступа нет

}

Обозначение :y(yy), m(mm), d(dd) указывает на то, как инициализируются члены. Оно называется списком инициализации. Мы могли бы написать эквивалентный фрагмент кода.

Date::Date(int yy, int mm, int dd) // конструктор

{

  y = yy;

  m = mm;

  d = dd;

}

Однако сначала нам следовало бы инициализировать члены их значениями, заданными по умолчанию, и лишь потом присваивать им новые значения. Кроме того, в этом случае не исключена возможность того, что мы случайно используем член класса до его инициализации. Обозначение :y(yy), m(mm), d(dd) точнее отражает наши намерения. Разница между этими фрагментами точно такая же, как между двумя примерами, приведенными ниже. Рассмотрим первый из них.

int x; // сначала определяем переменную x

// ...

x = 2; // потом присваиваем ей значение

Второй пример выглядит так:

int x = 2; // определяем и немедленно инициализируем двойкой

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

int x(2);               // инициализируем двойкой

Date sunday(2009,8,29); // инициализируем объект Sunday

                        // триадой (2009,8,29)

Функцию-член класса можно также определить в определении класса.

// простой класс Date (детали реализации будут рассмотрены позднее)

class Date {

public:

  Date(int yy, int mm, int dd)

  :y(yy), m(mm), d(dd)

  {

    // ...

  }

void add_day(int n)

{

  // ...

}

int month() { return m; }

  // ...

private:

  int y, m, d; // год, месяц, день

};

Во-первых, отметим, что теперь объявление класса стало больше и запутаннее. В данном примере код конструктора и функции add_day() могут содержать десятки строк. Это в несколько раз увеличивает размер объявления класса и затрудняет поиск интерфейса среди деталей реализации. Итак, мы не рекомендуем определять большие функции в объявлении класса. Тем не менее посмотрите на определение функции month(). Оно проще и короче,

1 ... 96 97 98 99 100 ... 337 ВПЕРЕД
Перейти на страницу:
Комментариев (0)