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


Авторские права

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

Здесь можно скачать бесплатно "Albert Makhmutov - Идиомы и стили С++" в формате fb2, epub, txt, doc, pdf. Жанр: Программирование. Так же Вы можете читать книгу онлайн без регистрации и SMS на сайте LibFox.Ru (ЛибФокс) или прочесть описание и ознакомиться с отзывами.
Рейтинг:
Название:
Идиомы и стили С++
Автор:
Издательство:
неизвестно
Год:
неизвестен
ISBN:
нет данных
Скачать:

99Пожалуйста дождитесь своей очереди, идёт подготовка вашей ссылки для скачивания...

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.

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

Как получить книгу?
Оплатили, но не знаете что делать дальше? Инструкция.

Описание книги "Идиомы и стили С++"

Описание и краткое содержание "Идиомы и стили С++" читать бесплатно онлайн.








 a-›set(9);

 t = a-›get();

// a.Push();

 t = a-›get();

 a.PopOne();

 t = a-›get();

 a.Rollback();

 t = a-›get();

 return 0;

}

Шаг 24 - Как создавать ТОЛЬКО локальные переменные.

В Шаге 17 мы изыскали способ подавить создание локальных переменных. Решим обратную задачу - как подавить иные способы их создания. А какие иные? Любые другие способы предполагают вызов оператора operator new() для выделения памяти и потом вызов конструктора. Значит, надо объявить operator new() закрытым членом класса, да и все. Ничего в нем делать не надо, а сразу назад. Попробуем?

class CNoHeap {

public:

 int a;

private:

 void* operator new(size_t size) { return NULL; }

};


int main () {

/*

CNoHeap* firstTestNoHeap = new CNoHeap; // Не откомпилируется

*/

 CNoHeap secondTestNoHeap; // А это пожалуйста.

 return 0;

}

Теперь, если определить макрос:

#define DECLARE_LOCAL \

 private: \

 void* operator new(size_t size) { return NULL; }

и потом вкладывать его во всякие разные объекты, отвечающие за захват и освобождение ресурсов, то получится весьма удобно; Вы ГАРАНТИРОВАННО освободите любые ресурсы, захваченные в конструкторе и освобождаемые в деструкторе, в том числе в исключении. В любом случае, всякое ограничение уменьшает энтропию.

Для Шага 17, где мы рисовали производящие и разрушающие функции, тоже можно нарисовать макрос… и назвать его DECLARE_DYNCREATE. То есть, я хочу сказать, что Вы можете аккуратно переписать нужное из него в свою версию, а в результате получите

class CSomeClass {

 DECLARE_NOLOCAL

public:

 bool Initialize (param list);

};

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

Шаг 25 - Как сделать виртуальной свободную функцию.

Чаще всего этот прием я видел в отношении оператора operator‹‹. Точнее, не чаще, а всегда. На нем и разберем. Пусть у нас есть иерархия классов, и мы хотим определить диагностическую функцию Dump(). Она должна вываливать диагностику в заданное что-то (CDestination). У нас есть два варианта: или сделать функцию виртуальной в иерархии классов:

class CBase {

 virtual void Dump(CDestination& ds) = 0;

};

class CFirst: public CBase {

 void Dump (CDestination& ds);

};

class CSecond: public CBase {

 void Dump (CDestination& ds);

};

Или перегружать ее для каждого класса иерархии или в классе, или в свободной функции:

CDestination {

 void Dump (CFirst& fs);

 void Dump (CSecond& sc);

};

void Dump (CDestination& ds, CThird& td);

void Dump (CDestination& ds, CFourth& fr);

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

Но у второго варианта есть одно преимущество: функцию Dump() можно обозвать оператором operator‹‹, и это будет выглядеть весьма презентабельно:

// Это декларация

CDestination {

 CDestination& operator‹‹ (CFirst& fs);

};

CDestination& operator‹‹ (CDestination& ds, CSecond& sc);


// А это применение

dStream ‹‹ dObject;

Как сделать так, чтобы сохранить замечательное полиморфное поведение первого варианта, и применить эту радость идиота operator‹‹? Легко: пусть operator‹‹ вместо реальной работы просто вызывает виртуальную Dump(). Именно так сделано в MFC - объект afxDump вызывает виртуальную Dump() именно через operator‹‹. (Можно что угодно говорить про Microsoft, но факт есть факт - огромное число полезных и интересных приемов использовано в их продуктах и "… взять их у нее - наша задача!").

#include ‹iostream.h›

class CNoChange;

class CBase {

public:

 virtual void passTo (CNoChange& _cb) { cout ‹‹ "base passed" ‹‹ endl; }

};


class CFirst: public CBase {

public:

 void passTo (CNoChange& _cb) { cout ‹‹ "first passed" ‹‹ endl; }

};


class CSecond: public CBase {

public:

 void passTo (CNoChange& _cb) { cout ‹‹ "second passed" ‹‹ endl; }

};


class CNoChange {

public:

 int a;

 // Это вариант с оператором - членом класса.

 CNoChange& operator‹‹ (CBase& _cb) { _cb.passTo(*this); return *this; }

};


// а это - свободная функция.

//CNoChange& operator‹‹ (CNoChange& _nc, CBase& _cb)

// {_cb.passTo(_nc); return _nc;};

// проверить надо.

int main() {

 CNoChange nc;

 CFirst fs;

 CSecond sc;

 nc‹‹fs;

 nc‹‹sc;

 return 0;

}

Шаг 26 - Как сделать массив из чего угодно. Продолжение 2.

Итераторы.

В Шагах 15 и 16 мы повозились с имитацией массива (коллекцией). Мы добились нормальной работы при чтении и записи в ячейки массива. Но работа с массивом этим не ограничивается. Вот захочется нам сделать что-то со всеми элементами массива, а он индексирован по строке.

// Бред

for (string cCounter= "a"; a ‹ "zzzz"; a++) array.[cCounter].doit();

Нет, это неправильно. Нужно сделать так, чтобы коллекция сама себя перебирала.

CIndex index = array.getStart();

while (!array.eof()) {

 index = array.getIndex ();

 array[index].doIt();

 array.getNext();

};

Ну вот, на что-то похоже. Появился некий элемент index класса CIndex, без которого в принципе можно обойтись, если коллекция будет хранить текущее значение перебора внутри себя. Но вот беда - если вдруг коллекцию захотят перебрать разные клиенты? Ну глобальная она, существует вместе с программой, а обращаются к ней разные объекты, как себя перебрать бедной коллекции? В общем, подход тут такой же, как и в жизни: тебе надо, ты и шевелись, в смысле перебирай. Упомянутый выше index тут как нельзя кстати. Называем его Зингельшухером… (oops!) Простите - итератором, объявляем его дружественным коллекции, прописываем в него текущую позицию, пишем скромный набор функций навигации типа goFirst, goNext, isLast. В зависимости от того, где мы их пишем, итератор будет или активным - если функции навигации в нем, или пассивным - если они лежат в коллекции.

Итак, что делаем: в шаблон ampstack‹Type› из Шага 23 вписываем дружбу к классу итератора:

friend class ampIter;

и сам шаблон класса итератора:

// Класс итератора, дружественный нашему стеку.

template ‹class Type›

class ampIter {

private:

 ampstack‹Type›* m_stack;

 int iPosition;

public:

 ampIter(ampstack‹Type›* _as = NULL) : m_stack(_as), iPosition (0) {}

 int isLast(void) { return iPosition + 1 - m_stack-›iTop; }

 void moveStart(void) {iPosition = 0; }

 Type* moveNext(void) { return m_stack-›array[iPosition++]; }

};

Итераторы - это тема, граничащая с безумием. Мы вовремя остановились на активном итераторе, шаблоне, не вложенном, с семантикой указателей. А ведь их можно вкладывать (т.е. объявлять класс итератора внутри класса коллекции), связывать с курсорами, перегружать их операторы, изменять семантику, вводить многопоточность, создавать внутри (!) итератора мгновенную частную копию коллекции и это только начало. По счастью, о нас уже позаботился Алексей Степанов, и подарил нам Библиотеку Стандартных Шаблонов - Standart Template Library, полную итераторов, равно коллекций и алгоритмов. Немного о них можно почитать на этом же сайте в разделе VC++-›STL у Артема Каева, а много - в MSDN.

Так же добавлю, что пользуюсь при подготовке Шагов компилятором BC3.1, а он поддерживает шаблоны не вполне так, как это делают современные компиляторы. То есть, если Вы просто скопируете код, вероятно он сразу даже не откомпилируется. Так что предупреждаю - если собираетесь пользоваться шаблонами - проверьте, что на эту тему думает компилятор (а так же насчет исключений и операторов вида xxxxxxx_cast‹›()).

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

Шаг 27 - Умные указатели. Перегрузка operator*, operator(),operator-›*.

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


На Facebook В Твиттере В Instagram В Одноклассниках Мы Вконтакте
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!

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

Книги похожие на "Идиомы и стили С++" читать онлайн или скачать бесплатно полные версии.


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

Все книги автора Albert Makhmutov

Albert Makhmutov - все книги автора в одном месте на сайте онлайн библиотеки LibFox.

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

Отзывы о "Albert Makhmutov - Идиомы и стили С++"

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

А что Вы думаете о книге? Оставьте Ваш отзыв.