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

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

Книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!

292 0 18:03, 26-08-2023
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
26 август 2023

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

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

    1 ... 191 192 193 194 195 196 197 198 199 ... 337
    Перейти на страницу:
    рекомендуем вам начинать с очень простых шаблонов и постепенно набираться опыта. Один из полезных приемов проектирования мы уже продемонстрировали на примере класса vector: сначала разработайте и протестируйте класс, используя конкретные типы. Если программа работает, замените конкретные типы шаблонными параметрами. Для обеспечения общности, типовой безопасности и высокой производительности программ используйте библиотеки шаблонов, например стандартную библиотеку языка C++. Главы 20-21 посвящены контейнерам и алгоритмам из стандартной библиотеки. В них приведено много примеров использования шаблонов.

    19.3.3. Контейнеры и наследование

    Это одна из разновидностей сочетания объектно-ориентированного и обобщенного программирования, которое люди постоянно, но безуспешно пытаются применять: использование контейнера объектов производного класса в качестве контейнера объектов базового класса. Рассмотрим пример.

    vector<Shape> vs;

    vector<Circle> vc;

    vs = vc;    // ошибка: требуется класс vector<Shape>

    void f(vector<Shape>&);

    f(vc);      // ошибка: требуется класс vector<Shape>

     

     Но почему? “В конце концов, — говорите вы, — я могу конвертировать класс Circle в класс Shape!” Нет, не можете. Вы можете преобразовать указатель Circle* в Shape* и ссылку Circle& в Shape&, но мы сознательно запретили присваивать объекты класса Shape, поэтому вы не имеете права спрашивать, что произойдет, если вы поместите объект класса Circle с определенным радиусом в переменную типа Shape, которая не имеет радиуса (см. раздел 14.2.4). Если бы это произошло, — т.е. если бы мы разрешили такое присваивание, — то возникло бы так называемое “усечение” (“slicing”), похожее на усечение целых чисел (см. раздел 3.9.2).

    Итак, попытаемся снова использовать указатели.

    vector<Shape*> vps;

    vector<Circle*> vpc;

    vps = vpc;  // ошибка: требуется класс vector<Shape*>

    void f(vector<Shape*>&);

    f(vpc);     // ошибка: требуется класс vector<Shape*>

    И вновь система типов сопротивляется. Почему? Рассмотрим, что может делать функция f().

    void f(vector<Shape*>& v)

    {

      v.push_back(new Rectangle(Point(0,0),Point(100,100)));

    }

     

     Очевидно, что мы можем записать указатель Rectangle* в объект класса vector<Shape*>. Однако, если бы этот объект класса vector<Shape*> в каком-то месте программы рассматривался как объект класса vector<Circle*>, то мог бы возникнуть неприятный сюрприз. В частности, если бы компилятор пропустил пример, приведенный выше, то что указатель Rectangle* делал в векторе vpc? Наследование — мощный и тонкий механизм, а шаблоны не расширяют его возможности неявно. Существуют способы использования шаблонов для выражения наследования, но эта тема выходит за рамки рассмотрения этой книги. Просто запомните, что выражение “D — это B” не означает: “C<D> — это C<B>” для произвольного шаблонного класса C. Мы должны ценить это обстоятельство как защиту против непреднамеренного нарушения типов. (Обратитесь также к разделу 25.4.4.) 

    19.3.4. Целые типы как шаблонные параметры

     

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

    Рассмотрим пример наиболее распространенного использования целочисленного значения в качестве шаблонного аргумента: контейнер, количество элементов которого известно уже на этапе компиляции.

    template<class T, int N> struct array {

      T elem[N]; // хранит элементы в массиве -

      // члене класса, использует конструкторы по умолчанию,

      // деструктор и присваивание

      T& operator[] (int n); // доступ: возвращает ссылку

      const T& operator[] (int n) const;

      T* data() { return elem; } // преобразование в тип T*

      const T* data() const { return elem; }

      int size() const { return N; }

    }

    Мы можем использовать класс array (см. также раздел 20.7) примерно так:

    array<int,256> gb; // 256 целых чисел

    array<double,6> ad = { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 }; // инициализатор!

    const int max = 1024;

    void some_fct(int n)

    {

      array<char,max> loc;

      array<char,n> oops;         // ошибка: значение n компилятору

                                  // неизвестно

      // ...

      array<char,max> loc2 = loc; // создаем резервную копию

      // ...

      loc = loc2;                 // восстанавливаем

      // ...

    }

    Ясно, что класс array очень простой — более простой и менее мощный, чем класс vector, — так почему иногда следует использовать его, а не класс vector? Один из ответов: “эффективность”. Размер объекта класса array известен на этапе компиляции, поэтому компилятор может выделить статическую память (для глобальных объектов, таких как gb) или память в стеке (для локальных объектов, таких как loc), а не свободную память. Проверяя выход за пределы диапазона, мы сравниваем константы (например, размер N). Для большинства программ это повышение эффективности незначительно, но если мы создаем важный компонент системы, например драйвер сети, то даже небольшая разница оказывается существенной. Что еще более важно, некоторые программы просто не могут использовать свободную память. Такие программы обычно работают во встроенных системах и/или в программах, для которых основным критерием является безопасность (подробно об этом речь пойдет в главе 25). В таких программах массив array имеет много преимуществ над классом vector без нарушения основного ограничения (запрета на использование свободной памяти).

    Поставим противоположный вопрос: “Почему бы просто не использовать класс vector?”, а не “Почему бы просто не использовать встроенные массивы?” Как было показано в разделе 18.5, массивы могут порождать ошибки: они не знают своего размера, они конвертируют указатели при малейшей возможности и неправильно копируются; в классе array, как и в классе vector, таких проблем нет. Рассмотрим пример.

    double* p = ad;        // ошибка: нет неявного преобразования

                           // в указатель

    double* q = ad.data(); // OK: явное преобразование

    template<class C> void printout(const C& c) // шаблонная функция

    {

      for (int i = 0; i<c.size(); ++i) cout << c[i] <<'n';

    Эту функцию printout() можно вызвать как в классе array, так и в классе vector.

    printout(ad); // вызов из

    1 ... 191 192 193 194 195 196 197 198 199 ... 337
    Перейти на страницу:
    1. Жалоба
    Отзывы - 0

    Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.


    Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

    • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
    • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
    • 3. Просьба отказаться от нецензурной лексики.
    • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

    Надеемся на Ваше понимание и благоразумие. С уважением, администратор LoveRead.info.


    Установить VPN и читай слушай бесплатно

    Новые отзывы

    1. Борис Борис14 июнь 00:50 Колокола в России тем и отличались от западных что раскачиаали именно язык колокола,а не сам колокол! Авторы что-жертвы ЕГЭ? Не... Соединенные Штаты России 3 - Полина Ром
    2. Людмила Хофман Людмила Хофман10 июнь 22:13 У меня перевернулся мир после прочтения ваших книг! Так приятно и чисто на душе, ведь по сути неважно кто с кем , а только любовь... Долгая игра - Рейчел Рид
    3. Анна Анна08 июнь 11:28 Спасибо за новую историю жизни и любви на сайте,прочитала с удовольствием .... Давай поженимся - Юлия Резник
    Все комметарии
    Новинки бесплатной онлайн библиотеки