Библиотека knigago >> Компьютеры: Языки и системы программирования >> C, C++, C# >> Идиомы и стили С++


Книга «Максимов Василий Максимович» Якова Минченкова представляет собой исчерпывающую и захватывающую биографию одного из самых выдающихся русских художников XIX века. Василий Максимов был выдающимся членом Товарищества передвижных художественных выставок и известен своими картинами, изображающими повседневную жизнь русского крестьянства. Минченков умело исследует жизнь и творчество Максимова, погружая читателя в его бедность, триумфы и неудачи. Книга начинается с детального изложения детства...

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

Идиомы и стили С++
Книга - Идиомы и стили С++.  Albert Makhmutov  - прочитать полностью в библиотеке КнигаГо
Название:
Идиомы и стили С++
Albert Makhmutov

Жанр:

Современные российские издания, Литература ХXI века (эпоха Глобализации экономики), Программирование: прочее, C, C++, C#

Изадано в серии:

неизвестно

Издательство:

неизвестно

Год издания:

-

ISBN:

неизвестно

Отзывы:

Комментировать

Рейтинг:

Поделись книгой с друзьями!

Помощь сайту: донат на оплату сервера

Краткое содержание книги "Идиомы и стили С++"

Аннотация к этой книге отсутствует.

Читаем онлайн "Идиомы и стили С++". [Страница - 3]

оператор.

T* operator-›() {

 if (!tObj) return spy;

 return tObj;

};

Здесь нужно пояснить: spy совсем не обязательно класса T. Можно воткнуть производный, и переопределить его функции. Тогда он будет Вам докладывать о попытках обращения к NULL. Не забудьте его создать, инициализировать, и прицепить к указателю. А то вся идея на помойку. Вы пытаетесь отловить обращение к NULL, а там… NULL!!! "Матрицу" видели?

2. Отладка и трассировка.

Ну это совсем банально. Выносим определение операторов за определение класса и ставим там точку останова. Чтобы не тормозило в релиз версии, окружаем слово inline ифдефами.

template ‹class T›

#ifndef DEBUG

inline

#endif

SmartPointer‹T›::operator T*() {

 return tObj;

}


template ‹class T›

#ifndef DEBUG

inline

#endif

T* SmartPointer‹T›::operator T-›() {

 return tObj;

}

3. Статистика классов и объектов.

Ну все, здесь уже совсем все просто. Ничего писать не буду, кроме напоминания о том, что всенепременнейше нужно определять статистические переменные класса, в том числе и для параметризированного (то бишь для шаблона), и ровно один раз.

4. Кэширование.

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

Так. Пока тормозим. Интересно, о чем я напишу следующий шаг?

Шаг 4 - О двойной диспетчеризации.

Предположим, у нас есть массив, в котором мы храним карту местности. Разумеется, что элементы массива разнообразные - дома, колодцы, казино… ничего общего. Кроме суперкласса - предка естественно.

CBuilding

¦

______¦_______

¦ ¦ ¦

CHouse CWell CCasino

А карту эту мы отражаем разными способами. И даже не то, что разными способами, а имеем для такой благой цели несколько видов карт. Ну я не знаю, не картограф. Черви и пики. Нет, ладно. Радиоактивность и карма.

CMap

|

____________

| |

CRadioMap CCarmaMap

И что получается? Кто будет себя отрисовывать? И кто кого? Для каждой комбинации наследников CBuilding и CMap свой уникальный алгоритм. Что делать то будем? Какие феерические решения приходят… нет… не вам! Вашему коллеге или начальнику или подчиненному в голову? Да они ни сном ни духом о двойной диспетчеризации! Они скорее всего предложат получить информацию о типе во время исполнения, и запузырить в Ваш прекрасный проект кривоногий switch (){}. Да еще и положить в каждый класс статический член с информацией о типе… Одно звучание предыдущей фразы наводит на подозрения. Но что делаем мы? вот что:

class CBuilding: {

public:

 virtual void doDraw(CMap* map)=0;

}


class CHouse: public CBuilding {

public:

 virtual void doDraw (CMap* map) {

 // ВОТ ОНА САМАЯ КОРКА!

  map-›doDraw(*this);

 }

};


// Эти такие же.

class CWell: public CBuilding {

public:

 virtual void doDraw (CMap* map) {map-›doDraw(*this);}

};


class CCasino: public CBuilding {

public:

 virtual void doDraw (CMap* map) {map-›doDraw(*this);}

};


// Это абстрактный класс для карт.

class CMap {

public:

 virtual void doDraw (CHouse& cb)=0;

 virtual void doDraw (CWell& cb)=0;

 virtual void doDraw (CCasino& cb)=0;

};

Это конечно не все. Теперь нужно наследовать CRadioMap и CcarmaMap от общего предка CMap и в каждом классе рисовать реализацию алгоритма. За отрисовку отвечает карта, но какая масть - решает виртуальная CBuilding::doDraw(), а какое строение - выбирается перегруженная CMap::doDraw().

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

Круто? Это - подвиг неизвестного программиста. У Элджера был разобран пример со сложением чисел, очень красивый, но не сразу понятный. Там числа происходят от одного предка, что левый, что правый операнд оператора +, и по моему, обе диспетчеризации происходят по механизму виртуальных функций. Увы, мне лень набирать код.

Код к данному шагу я не проверял, в отличие от предыдущих. К диспетчеризации мы еще вернемся. Или не вернемся. Но следующий шаг однозначно про указатели.

Шаг 5 - Ведущие указатели (Master Pointers). Важные конструкторы.

Если мы уж взялись заниматься умными указателями, то очень быстро придем к выводу, что неплохо ограничить их свободу --">

Оставить комментарий:


Ваш e-mail является приватным и не будет опубликован в комментарии.