Читаем Идиомы и стили С++ полностью

Ну, положим, Вам необходимо работать с геологической картой. Размер 1000х1000. Пять слоев. Если решать в лоб, то только для хранения и обработки геологических условий нужно иметь пять миллионов элементов. Совершенно ясно, всем и каждому, что создавать карту на основе простого массива абсолютно недопустимо. По видимому, объект карты должен хранить информацию только в ключевых точках, а значения между ними вычислять; при необходимости записи в карту следует проверять - есть ли такая точка во внутренней структуре, и если есть - записывать в нее, а если нет - создавать ее.

Наша карта сильно стала похожа на разреженный массив. Отличие в том, что в классическом разреженном массиве между "ключевыми" элементами хранятся нули, а у нас там лежит (как будто) значение предыдущего элемента. Процессы чтения и записи существенно различаются; в предыдущем шаге мы могли работать со ссылкой, читать и записывать ее. Сейчас операция чтения возвращает нам какую-то неопознанную… или неучтенную… шняжку новогоднюю, толку в нее писать никакого, она все равно свежевычисленная. Операция записи пишет. Вещи абсолютно разные, ничего общего. Авторитетные специалисты пишут: "никакого толку от оператора [],… возможности разделить чтение и запись нет… надо писать на BASIC… на бумажечке".

Они не правы.

Выход есть. Нужно взять новогоднюю шняжку, опознать и учесть ее. Потом перегрузить у ней операторы operator[], operator-› и оператор приведения типа к элементу массива. Вы узнаете ее? Да это сэр Хьюго Баскервиль собственной персоной, он же Умный Указатель, он же Курсор, он же Proxy-объект! Вот черт, кто бы знал… Далее его именуем Курсором за сходство с аналогом из баз данных.

Так теперь перед кодом давайте самое важное вычленим:

1. Массив возвращает в операторе operator[] курсор.

2. Курсор имеет перегруженный оператор присваивания operator=, что позволяет нам грамотно обрабатывать вставки и записи в массив.

3. Курсор может неявно преобразовываться к значению элемента массива, что позволяет нам грамотно читать из массива.

4. Курсор имеет перегруженный оператор operator-›, что позволяет нам читать и… и в общем все, что нужно; смотри предыдущие шаги.

Теперь мы имеем семантический массив. Внутри может быть что угодно, но снаружи он совершенно неотличим, вообще. Элджер справедливо замечает: "внутреннюю реализацию Вы можете сменить даже на последних стадиях разработки". Я справедливо замечаю: "и ни одна… не до…". (Вообще это нам сержант Прищепкин говорил по поводу начищенности пряжки, но и здесь вполне подходит).

Еще по коду: Я написал для примера код, имитирующий базу данных наподобие SQL, потом засунул базу в класс такого массива и все такое… но получилось около 300 строк, и наглядность совсем пропала. Так что беру попроще - связанный список.

class CThat {int a;};

class CCursor;

class CArray;

class CNode;

class CNode {

public:

 int index;

 CThat* that;

 CNode* next;

 CNode (int _index, CThat* _that, CNode* _next): index(_index), that(_that), next(_next) {}

};

class CCursor {

public:

CArray* array;

int index;

CNode* node;

CCursor(CArray* _array, int _index):

array(_array), index(_index), node (NULL){};

CCursor(CArray* _array, CNode* _node):

array(_array), index (_node-›index), node (_node){};

CCursor& operator=(CThat* _that);

operator CThat*;

CThat* operator-›;

};

class CArray {

public:

 CNode* cells;

 CArray: cells(NULL) {}

 CCursor operator[](int i);

};

CCursor CArray::operator[](int _index) {

 CNode* pNode = cells;

 while (pNode!=NULL) {

  if (pNode-›index -_index) {

   return CCursor(this, pNode);

  } else pNode=pNode-›next;

 }

 return CCursor(this, _index);

}

CCursor& CCursor::operator=(CThat* _that) {

 if (node==NULL) {

  node = new CNode (index, _that, array-›cells);

  array-›cells = node;

 } else {

  node-›that = _that;

 }

 return *this;

}

CCursor::operator CThat* {

Перейти на страницу:

Похожие книги

Основы программирования в Linux
Основы программирования в Linux

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов

Нейл Мэтью , Ричард Стоунс , Татьяна Коротяева

ОС и Сети / Программирование / Книги по IT
97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

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

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT
Программист-прагматик. Путь от подмастерья к мастеру
Программист-прагматик. Путь от подмастерья к мастеру

Находясь на переднем крае программирования, книга "Программист-прагматик. Путь от подмастерья к мастеру" абстрагируется от всевозрастающей специализации и технических тонкостей разработки программ на современном уровне, чтобы исследовать суть процесса – требования к работоспособной и поддерживаемой программе, приводящей пользователей в восторг. Книга охватывает различные темы – от личной ответственности и карьерного роста до архитектурных методик, придающих программам гибкость и простоту в адаптации и повторном использовании.Прочитав эту книгу, вы научитесь:Бороться с недостатками программного обеспечения;Избегать ловушек, связанных с дублированием знания;Создавать гибкие, динамичные и адаптируемые программы;Избегать программирования в расчете на совпадение;Защищать вашу программу при помощи контрактов, утверждений и исключений;Собирать реальные требования;Осуществлять безжалостное и эффективное тестирование;Приводить в восторг ваших пользователей;Формировать команды из программистов-прагматиков и с помощью автоматизации делать ваши разработки более точными.

А. Алексашин , Дэвид Томас , Эндрю Хант

Программирование / Книги по IT