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

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

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

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

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

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

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

Перейти на страницу:
функций десяток, нам будет намного проще работать, чем если их будет пятьдесят.

Пятьдесят функций для класса Date! Возможно, вы думаете, что мы шутим. Вовсе нет: несколько лет назад я делал обзор нескольких коммерческих библиотек для работы с календарем и обнаружил в них множество функций вроде next_Sunday(), next_workday() и т.д. Пятьдесят — это совсем не невероятное число для класса, разработанного для удобства пользователей, а не для удобства его проектирования, реализации и сопровождения.

Отметим также, что если представление изменяется, то переписать достаточно только функции, которые имеют к ней прямой доступ. Это вторая важная практическая причина для минимизации интерфейса. Разрабатывая класс Date, мы могли решить, что дату лучше представлять в виде целого числа дней, прошедших с 1 января 1900 года, а не в виде тройки (год, месяц, день). В этом случае нам придется изменить только функции-члены.

Рассмотрим несколько примеров вспомогательных функций (helper functions).

Date next_Sunday(const Date& d)

{

  // имеет доступ к объекту d, используя d.day(), d.month()

  // и d.year()

  // создает и возвращает новый объект класса Date

}

Date next_weekday(const Date& d) { /* ... */ }

bool leapyear(int y) { /* ... */ }

bool operator==(const Date& a, const Date& b)

{

  return a.year()==b.year()

  && a.month()==b.month()

  && a.day()==b.day();

}

bool operator!=(const Date& a, const Date& b)

{

  return !(a==b);

}

 

 Вспомогательные функции также называют функциями-помощниками. Различие между этими и другими функциями, не являющимися членами класса, заключается в логике работы; иначе говоря, вспомогательная функция представляет собой концепцию проектирования, а не концепцию языка программирования. Вспомогательная функция часто получает в качестве аргументов объекты класса, для которого они играют вспомогательную роль. Хотя существуют исключения, например функция leapyear(). Часто для идентификации вспомогательных функций используются пространства имен (см. раздел 8.7).

namespace Chrono {

class Date { /* ... */ };

  bool is_date(int y, Date::Month m, int d); // true для

                                             // корректных данных

  Date next_Sunday(const Date& d) { /* ... */ }

  Date next_weekday(const Date& d) { /* ... */ }

  bool leapyear(int y) { /* ... */ } // см. пример 10

  bool operator==(const Date& a, const Date& b) { /* ... */ }

  // ...

}

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

Отметьте также, что мы ввели вспомогательную функцию is_date(), которая заменяет функцию Date::check(), поскольку проверка корректности даты во многом не зависит от представления класса Date. Например, нам не нужно знать, как представлены объекты класса Date для того, чтобы узнать, что дата “30 января 2008 года” является корректной, а “30 февраля 2008 года” — нет. Возможно, существуют аспекты даты, которые зависят от ее представления (например, корректна ли дата “30 января 1066 года”), но (при необходимости) конструктор Date может позаботиться и об этом.

9.8. Класс Date

Итак, соединим все идеи и понятия вместе и посмотрим, как будет выглядеть класс Date. Там, где тело функции содержит лишь комментарий ..., фактическая реализация слишком сложна (пожалуйста, не пытайтесь пока ее написать). Сначала разместим объявления в заголовочном файле Chrono.h.

// файл Chrono.h

#include "Chrono.h"

namespace Chrono {

class Date {

public:

  enum Month {

    jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec

  };

class Invalid { }; // для генерации в виде исключения

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

  Date();                    // конструктор по умолчанию

                             // операции копирования по умолчанию

                             // в порядке

  // немодифицирующие операции:

  int day() const { return d; }

  Month month() const { return m; }

  int year() const { return y; }

  // модифицирующие операции:

  void add_day(int n);

  void add_month(int n);

  void add_year(int n);

private:

  int y;

  Month m;

  int d;

};

bool is_date(int y, Date::Month m, int d); // true для корректных дат

bool leapyear(int y); // true, если y — високосный год

bool operator==(const Date& a, const Date& b);

bool operator!=(const Date& a, const Date& b);

ostream& operator<<(ostream& os, const Date& d);

istream& operator>>(istream& is, Date& dd);

} // Chrono

Определения находятся в файле Chrono.cpp.

// Chrono.cpp

namespace Chrono {

// определения функций-членов:

  Date::Date(int yy, Month mm, int dd)

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

  {

    if (!is_date(yy,mm,dd)) throw Invalid();

  }

  Date& default_date()

  {

    static Date dd(2001,Date::jan,1); // начало XXI века

    return dd;

  }

  Date::Date()

       :y(default_date().year()),

        m(default_date().month()),

        d(default_date().day())

  {

  }

  void Date:: add_day(int n)

  {

    // ...

  }

  void Date::add_month(int n)

  {

    // ...

  }

  void Date::add_year(int n)

  {

    if (m==feb && d==29 && !leapyear(y+n)) { // помните о високосных годах!

      m = mar; // 1 марта вместо

               // 29 февраля

      d = 1;

    }

    y+=n;

  }

  // вспомогательные функции:

  bool is_date(int y, Date::Month m, int d)

  {

    // допустим, что y — корректный объект

    if (d<=0) return false; // d должна быть положительной

    if

Перейти на страницу:
Комментариев (0)