С++ - язык, который изучается постепенно.ГЛАВА 16. Итераторы ведущих указателей

Недорогой но высококачественный сайт. Такое может быть? Да. У нас может быть всё. Достойное качество по доступной цене.
С точки зрения нашей студии создание сайта недорого значит, прежде всего, отменно, технологично и потом уже - недорого.
Удаленная форма работы с клиентами оптимизирует наши расходы и мы можем делать сайты по всему миру. Вам совсем не нужно приезжать к нам. Мы сэкономим Ваше время и средства.

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


По последним данным, на рынке продается по крайней мере 2 768 942 книги о С++, не говоря уже о всевозможных курсах, обучающих программах, журналах и семинарах с коктейлями. И все же в этом изобилии наблюдается удручающее однообразие. Просматривать полку книг о С++ в книжном магазине ничуть не интереснее, чем литературу по бухгалтерии. В сущности, все книги пересказывают одно и то же и отличаются разве что по весу и количеству цветов в диаграммах и таблицах.На сегодняшний день язык Си и языки основанные на синтаксисе Си (например, C++, Java, C#) наиболее популярны в практическом программировании. Язык Си имеет массу достоинств, он прост в изучении и лаконичен. Элементы языка Си (массивы, функции, указатели) максимально приближены к архитектуре компьютеров. Студия Web-дизайна, создание, раскрутка сайта

                    



Материалы книги получены с http://www.itlibitum.ru/

Итераторы ведущих указателей

Помните VoidPtrIterator? VoidPtrPool возвращает один итератор для перебора всех указателей с

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

интерпретируется по-другому. Раньше ненулевой счетчик ссылок означал, что объект не следует уничтожать. Теперь он имеет более узкое значение: объект доступен непосредственно из стека. Все эти объекты сохраняются, поскольку они находятся на периметре, но мы также сохраним объекты с нулевыми счетчиками ссылок, если они доступны косвенно.

Для объектов внутри периметра мы должны перебрать дескрипторы каждого объекта периметра, а затем рекурсивно двигаться внутрь до тех пор, пока не будут перебраны все доступные объекты. Для этого нам придется анализировать объекты одним из описанных выше способов. В данном примере будет использовано сочетание виртуальных функций/итераторов. Для этой цели можно слегка переработать старый интерфейс VoidPtrIterator.

class VoidPtrIterator {

protected:

VoidPtrIterator() {}

public:

virtual bool More() = 0;

virtual VoidPtr* Next() = 0;

};

Теперь пул должен поддерживать два типа итераторов. Один итератор перебирает указатели, находящиеся на периметре (то есть имеющие ненулевые счетчики ссылок). Второй - указатели на объекты, находящиеся в указанной половине. Итератор VoidPtrPool::iterator() из главы 15 заменяется следующим:

// Включить в класс VoidPtrPool

class VoidPtrPool {

public:

VoidPtrIterator* Reachable()

{ return new ReachableIterator(this); }

VoidPtrIterator* InRange(void* low, void* high)

{ return new RangeIterator(this); }

};

Указатели периметра

Один из типов итераторов, возвращаемых пулом, перебирает непосредственно доступные указатели (имеющие ненулевой счетчик ссылок). В сущности, перед нами тот же VoidPtrPoolIterator с одной изменившейся строкой - теперь Advance() пропускает позиции с нулевым счетчиком ссылок. Класс реализован как производный от VoidPtrPoolIterator.

class ReachableIterator : public VoidPtrPoolIterator {

protected:

virtual void Advance() // Найти следующую используемую позицию

{

do

VoidPtrPoolIterator::Advance();

while (block != NULL && block->slots[slot].refcount == 0);

}

public:

ReachableIterator(VoidPtrBlock* vpb) : VoidPtrPoolIterator(vpb) {}

};

Недоступные указатели

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

class InRange : public VoidPtrPoolIterator {

private:

void* low; // Нижний адрес диапазона

void* high; // Верхний адрес диапазона

virtual void Advance() // Найти следующуюиспользуемую позицию

{

do

VoidPtrPoolIterator::Advance();

while (block != NULL &&

(block->slots[slot].address < low ||

block->slots[slot].address >= high));

}

public:

InRange(VoidPtrBlock* vpb, void* low_addr, void* high_addr)

: VoidPtrPoolIterator(vpb), low(low_addr), high(high_addr) {}

};

Перебор указателей в объектах

Каждый объект возвращает другой итератор VoidPtrIterator, который перебирает указатели,

доступные непосредственно из объекта. Для каждого класса этот итератор должен быть своим. Далее показан пример.

class MotherOfAllObject { // Базовый класс для всех остальных

public:

virtual VoidPtrIterator* Pointers() = 0;

};

template <class Type>

class VoidPtrArrayIterator : public VoidPtrIterator {

private:

VoidPtr* ptrs[Entries];

int next; // Следующая позиция в переборе

public:

VoidPtrArrayIterator() : next(0)

{

for (int i = 0; i < Entries; i++)

ptrs[i] = NULL;

}

VoidPtr*& operator[](uint slot) { return ptrs[slot]; }

virtual bool More() { return next < Entries; }

virtual VoidPtr* Next() { return ptrs[next++]; }

};

// Пример класса и итератора

class Foo {

private:

WH<Bar> bar;

public:

virtual VoidPtrIterator* Pointers()

{

new VoidPtrArrayIterator<1>* iterator = new VoidPtrArrayIterato<1>;

iterator[0] = bar.Pointer();

return iterator;

}

};

VoidPtrArrayIterator сделан на скорую руку и в реальном проекте его использовать не стоит, но по крайней мере он демонстрирует общий принцип. Конечно, его следует дополнить проверками диапазонов и инициированием исключений, если будет затребован VoidPtr* для NULL. Foo::Pointers() показывает общий принцип использования VoidPtrArrayIterator. Для каждого

класса мы изменяем размер массива, чтобы он совпадал с количеством WH<Widget> и добавляем для каждого дескриптора по одной строке вида iterator(index++) = widget.Pointer(). Этот шаблон справляется со всеми простыми случаями, в которых нам не приходится беспокоиться о базовых классах. Если Foo имеет базовые классы, придется организовать вложение итераторов для его собственных указателей и указателей базовых классов.


Назад    Содержание    Далее    

   Почти всегда целью создания сайта является получение прибыли, которая в свою очередь, зависит от его внешнего вида. Статистика говорит, что около 94% людей, при выборе товара, сначала обращают внимание на упаковку, а потом уже на её содержимое. И если эта упаковка не привлекательная и безвкусная, мало кто обратит на нее внимание, и, соответственно, товар не будет пользоваться спросом.
   В случае с интернет, “упаковкой” выступает ваш сайт, а “товаром” - его контент. Если сайт выглядит непривлекательно, то каким бы ценным и нужным не было его содержимое, люди будут обходить его стороной. Наша задача - сделать ваш сайт привлекательным и удобным, чтобы люди чувствовали себя уютно и комфортно, чтоб они возвращались к вам еще и еще. Соответствие между ценой и качеством вас, несомненно, порадуют.
.
   Мы делаем сайты для бизнеса, а не красочную картинку, которая увешена тяжеловесными флэшами и огромными фотографиями.
   Пользователя, когда он попадает на абсолютно любой сайт, прежде всего интересует информация, затем, как реализовать на этом сайте полученную информацию, чтобы было удобно и просто (юзабилити), подбор цветовой гаммы, расположение блоков на странице и многое другое.

   Перед тем, как заказывать создание сайта, рекомендуем прочесть статью А зачем мне (нам) сайт? или Что нужно знать заказчику сайта
Да и вообще, обратите внимание на раздел Статьи о продвижении сайта и бизнеса там вы найдёте ответы на многие вопросы.