Albert Makhmutov - Идиомы и стили С++

Тут можно читать онлайн Albert Makhmutov - Идиомы и стили С++ - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Идиомы и стили С++
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    4.13/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Albert Makhmutov - Идиомы и стили С++ краткое содержание

Идиомы и стили С++ - описание и краткое содержание, автор Albert Makhmutov, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Идиомы и стили С++ - читать онлайн бесплатно полную версию (весь текст целиком)

Идиомы и стили С++ - читать книгу онлайн бесплатно, автор Albert Makhmutov
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

class CArray {

private:

int a[100];

int iTop;

public:

CArray ():iTop(0) {}

CArray (const CArray& _ca) {

iTop = _ca.iTop;

for (int i=0; i++; i ‹100) a[i]= _ca.a[i];

}

CArray& operator=(const CArray& _ca) {

if (this==&_ca) return *this;

for (int i=0; i++; i ‹100) a[i]= _ca.a[i];

iTop = _ca.iTop;

return *this;

};

// С этим еще можно согласиться

CArray& operator+ (int _i) { a[iTop]=_i; iTop++; return *this; }

// Это пример дурного стиля

int operator-- () { iTop--; return a[iTop+1]; }

};

Для такого тестового стека определим оператор operator+operator+=) для вставки объектов, а оператор operator-для выталкивания и удаления. Вы кстати знаете, что для operator++и operator-есть постфиксная и префиксная форма? У постфиксной в скобках фиктивный параметр стоит:

const type& operator++(); // Префиксная

type operator++(int); // Постфиксная.

Я позволяю себе пропустить кучу деталей (например то, что вставка сто первого элемента слегка повесит программу), но обращаю внимание: определение конструктора копии и оператора присваивания - суровая необходимость. Не сделаете - пожалеете; почему - говорил в Шаге 5.

Еще нюанс: определение operator--для выбора из стека есть, мягко говоря, спорный стиль; некоторые считают даже перегрузку operator‹‹и operator››для работы с потоками крайне неудачной идеей. Так что это я только для примера…

Пример имеет семантику значений, а не семантику указателей. Это в общем значит, что в коллекции хранятся примитивные значения, а не указатели или ссылки.

Кстати, запомните эти умные слова, их круто вставить в разговор с приятелями или (еще лучше) с начальством, чтобы запутать его в камом-нибудь вопросе или снять с себя ответственность за неверно принятые решения. Если особенно ответственность лежит так же и на начальстве (оно же и аналитик), то объяснение "так и так, тут семантика значений" будет воспринято лучше, чем "вы все - тупицы и недоучки, неспособные к проектированию и анализу". Вообще, теоретические познания бывают как нельзя более кстати при поиске виновных, чем при повседневной работе. Вы можете колбасить программы на фокспре или хотя и на C++c MTSи DCOM, но если Ваша программа повесит сервер бухгалтерии за день до зарплаты или годового отчета… то никакие познания не будут лишними, чтобы свалить вину на сисадминов!

Перед тем, как закончить Шаг, вернусь к стилю: если я для примера безграмотно переопределил операторы арифметики, это не значит, что то же самое должны делать Вы. Компилятор позволяет определить любое возвращаемое значение и запрограммировать любые действия, но понемногу изменяя семантику, в конце концов Вы выроете себе яму и попадете в нее. Есть еще одна опасность - поведение, приоритет и правила взаимодействия операторов ЗАДАНЫ раз и навсегда, а компилятор не может оценить Ваш интеллектуальный уровень, и действует так, как ДОЛЖЕН, а не так, как Вы ДУМАЕТЕ, что он должен. Из-за этого НИКОГДА не переопределяйте операторы operator&&()и operator||(), и всегда правильно задавайте возвращаемое значение операторов.

Шаг 14 - Двойная диспетчеризация. Продолжение.

В Шаге 4 мы говорили о двойной диспетчеризации. Она очень хорошо подходит при необходимости отображения одних объектов посредством других, но не только; она в общем применима, когда Вам нужно обрабатывать попарные (и более) взаимодействия объектов двух и более разных классов. Получается этакая табличка, на осях которой нарисованы классы, а в ячейках - функции их взаимодействия. Количество функций равно произведению столбцов и строк этой таблички. А если диспетчеризация тройная или выше? Тогда еще умножаем на количество слоев, и дальше и дальше…

Как бы упростить жизнь? А вот так - если взаимодействие двух объектов дает один результат, пусть этим и занимается одна функция. Попробуем перевести на человеческий язык:

Пусть есть класс CTitanicи класс CIceberg. Их карма в том, чтобы столкнуться. Четыре варианта взаимодействия: Столкновение двух Ctitanicне ведет ни к чему, если вообще возможно, двух CIceberg- у них там свои дела, столкновение CTitanicи CIceberg, как известно, к семи Оскарам, и столкновение CIcebergи CTitanic- к тому же самому. То есть функций всего три. Определим взаимодействие этих классов как функцию hit(). Вот код:

#include ‹iostream.h›

// Форвардные объявления

class CTitanic;

class CIceberg;

class CFloating;

// Абстрактный базовый класс

class CFloating {

public:

virtual void hit(CIceberg&)=0;

virtual void hit(CTitanic&)=0;

public:

virtual void hit(CFloating&)=0;

};

// Класс айсберга

class CIceberg {

public:

virtual void hit(CIceberg&);

virtual void hit(CTitanic&);

public:

virtual void hit(CFloating&);

};

// Первая диспетчерская функция

void CIceberg::hit(CFloating& _co) {

_co.hit(*this);

}

// Две реализации взаимодействия

void CIceberg::hit(CIceberg& _ci) {

cout ‹‹ "ci+ci" ‹‹ endl;

}

void CIceberg::hit(CTitanic& _ct) {

cout ‹‹ "ci+co" ‹‹ endl;

}

// Класс Титаника

class CTitanic {

public:

virtual void hit(CIceberg&);

virtual void hit(CTitanic&);

public:

virtual void hit(CFloating&);

};

// Еще одна диспетчерская функция

void CTitanic::hit(CFloating& _co) { _co.hit(*this); }

// А вот эта функция могла бы быть реализацией

// но мы ее тоже делаем диспетчерской;

// в этом фрагменте диспетчеризация тройная.

void CTitanic::hit(CIceberg& _ci) {

// cout ‹‹ "co+ci" ‹‹ endl; Это могла быть реализация

_ci.hit(*this);

}

void CTitanic::hit(CTitanic& _ct) {

cout ‹‹ "co+co" ‹‹ endl;

}

// проверим по быстрому, как работает

int main () {

CIceberg i1;

CTitanic t1;

CIceberg i2;

CTitanic t2;

i1.hit(t1);

i1.hit(i2);

t1.hit(i1);

t1.hit(t2);

return 0;

}

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

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

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

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Albert Makhmutov читать все книги автора по порядку

Albert Makhmutov - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Идиомы и стили С++ отзывы


Отзывы читателей о книге Идиомы и стили С++, автор: Albert Makhmutov. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x