10 июля 2017 · cpp · программирование

Полиморфная кухня. Часть 5. C++11 и C++14

В пятой части серии рассмотрим возможности наследования и полиморфизма, которые появились в стандарте C++11, а также C++14.

Возьмём иерархию из предыдущей статьи (исходный текст см. там же).

Читать далее →



7 января 2017 · cpp · программирование

Полиморфная кухня. Часть 4. Приведение dynamic_cast и RTTI

Как у наших ворот за горою
Жил да был бутерброд с колбасою.
Захотелось ему прогуляться,
На траве-мураве поваляться.
И сманил он с собой на прогулку
Краснощёкую сдобную булку.
Корней Чуковский

В трёх первых частях серии мы подробно рассмотрели многие аспекты, касающиеся наследования и полиморфизма в C++. Сегодня поговорим о динамическом приведении типа и об идентификации типа на этапе исполнения программы.

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

Как всегда, придумаем какую-нибудь несложную иерархию.

Читать далее →



27 декабря 2016 · cpp · программирование

Полиморфная кухня. Часть 3. Множественное и виртуальное наследование

В первой части серии мы рассмотрели основы наследования и полиморфизма в языке C++, во второй рассмотрели механизм, благодаря которому всё это работает. Идём дальше: создадим более замысловатую иерархию.

Сегодня реализуем следующую иерархию. Базовым классом будет класс Cmyk, реализующий цветовую схему CMYK. Класс CmykGy будет содержать дополнительный серый, класс CmykLcLm — дополнительные светло-синий и светло-малиновый. Класс CmykGyLcLmLg внизу иерархии будет содержать все упомянутые дополнительные цвета (серый, светло-синий, светло-малиновый), а также светло-серый.

                                          Cmyk
                             ┌──────────────┴──────────────┐
                          CmykGy                        CmykLcLm		
		             └──────────────┬──────────────┘
			               CmykGyLcLmLg

Читать далее →



19 октября 2016 · cpp · программирование

Полиморфная кухня. Часть 2. Таблицы виртуальных функций

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

Повторим основные моменты. Если в классе есть хотя бы одна функция с ключевым словом virtual, то она считается виртуальной, а сам класс — полиморфным. Для каждого полиморфного класса создаётся специальная таблица — таблица виртуальных функций. А каждый объект любого из полиморфных классов дополняется указателем на одну из таких таблиц.

Рассмотрим простую иерархию: розетка и заземлённая розетка.

                                          SocketGroundedSocket

Читать далее →



25 августа 2016 · cpp · программирование

Полиморфная кухня. Часть 1. Наследование и полиморфизм в C++

В языке C++ наследование и полиморфизм — очень важные понятия. Эта тема довольно обширна, для её понимания необходимо хорошо уяснить для себя, как объекты реального мира соотносятся с объектами в языке, как и когда происходит создание и уничтожение объектов, как работать с памятью, ссылками, указателями и зачем необходимы списки инициализации. Не лишним будем знание стандартных контейнеров, умных указателей и понимание смысла константности.

Напишем класс Pancake. Добавим три поля: радиус блинчика, толщину и сорт муки. Конструктор этого класса снабдим списком инициализации. Последний штрих — напишем функцию print().

class Pancake
{
public:
    Pancake(int radiusMm, int thicknessMm, int flourSort) :
        radiusMm_(radiusMm),
        thicknessMm_(thicknessMm),
        flourSort_(flourSort)
    {
    }

    void print() const
    {
        std::cout << "Pancake." << std::endl;
    }

protected:
    unsigned radiusMm_;     // RRRRRRRR RRRRRRRR RRRRRRRR RRRRRRRR
    unsigned thicknessMm_;  // TTTTTTTT TTTTTTTT TTTTTTTT TTTTTTTT
    char flourSort_;        // SSSSSSSS 00000000 00000000 00000000
};

Читать далее →



15 июля 2015 · cpp · математика · программирование

Запятая, Карл! Как устроены типы float и double

Плавающая запятая даёт много преимуществ, но «заплыв» этот полон моментов, требующих понимания и тщательного подхода. Числа с плавающей запятой используются слишком часто, чтобы пренебрегать их глубоким пониманием. Поэтому нужно хорошо разбираться, как представлены числа с плавающей запятой и как работают вычисления с ними.

Экскурс

Число с плавающей запятой представлено в следующем виде:

N = [s] × m × 2e,

где m — мантисса (23 бита — дробная часть мантиссы и неявно заданный ведущий бит, всегда равный единице, поскольку мантисса хранится в нормализованном виде), e — смещённая экспонента/порядок (8 бит). Один бит отводится под знак (s, бит равен нулю — число положительное, единице — отрицательное).

Тип double полностью аналогичен float, он лишь содержит больше битов мантиссы и порядка.

Рассмотрим какой-нибудь пример. Число 3,5 будет представлено в следующем виде:

Читать далее →



20 апреля 2015 · cpp · программирование

Массив здорового человека. Теперь в 3D!

В прошлой статье разбирались достоинства и недостатки различных форм представления массивов в памяти. В этот раз рассмотрим трёхмерный случай (и вообще N-мерный) и обратим внимание на то, как производится пересчёт логических координат в фактические.

Сперва вернёмся к двумерному случаю. Обращение к j-му элементу, раположенному в i-й строке, выглядит следующим образом: array_of_a_healthy_man[i * w + j] (w — количество элементов в строке). На рисунке представлено логическое и фактическое представление двумерного массива. Таким образом, слагаемое i * w означает «пропустить i строк, содержащих по w элементов».

Читать далее →



12 апреля 2015 · программирование · cpp

Массив здорового человека

Задача проста: организовать хранение двумерного массива. Во время написания некоторой программы один из моих учеников использовал два разных способа представления двумерного массива в памяти, оба из них не были эффективными, хотя вопрос хранения данных на стеке и в куче уже нами обсуждался. Другой студент, когда я попросил прокомментировать разные способы выделения памяти, испытал затруднения. Получается, что всё бывает не так очевидно, как кажется. А представить визуально и сказать с использованием точных терминов то, что описывается в коде, и вовсе оказывается сложной задачей.

Пусть необходимо хранить следующий массив элементов типа int размерностью 5×10.

35 58 73 32 35 32 59 95 19 39
64 54 45 73 52 20 92 76 94 92
47 93 65 14 25 92 27 93 14 94
90 45 85 31 69 32 95 12 87 53
75 11 47 72 33 42 58 62 57 85

Самый адекватный вариант в большинстве случаев — выделить в куче один массив для всех элементов.

const int w = 10, h = 5;
int* array_of_a_healthy_man = new int[h * w];

Читать далее →



26 сентября 2014 · it · apache · у меня будет свой хабр

Apache для пряничков. Простые перенаправления (в картинках)

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

Читать далее →