С++ - язык, который изучается постепенно. Самомодификация и переходимость
создание сайта визитки
Студия Web-дизайна, создание, раскрутка сайтов интернет реклама, подача объявлений на доски, продвижение и сопровождение сайтов
Карта сайта | Зарабатывайте с нами  | Сделать заказ
Наши услуги
Справочники
Самоучитель Internet Explorer
PHP и MySQL
Компьютерные сети
Самоучитель о С++
Новости
Новости для PDA
Реклама
Студия WebKuban.Ru - Создание и поддержка сайтов, интернет магазинов Каталог сайтов Всего.RU Интернет-каталог WWW.SABRINA.RU Refo.ru - русские сайты Каталог HeadNet.Ru Интернет-магазин цифровых товаров Каталог Ресурсов Интернет
Реклама
Язык С++
По последним данным, на рынке продается по крайней мере 2 768 942 книги о С++, не говоря уже о всевозможных курсах, обучающих программах, журналах и семинарах с коктейлями.
И все же в этом изобилии наблюдается удручающее однообразие.
Добро пожаловать на сайт студии Web-дизайна "САР"


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

Самомодификация и переходимость

Невидимый ведущий указатель, как и любой умный указатель, может интерпретироваться как

переходный тип. Если просто заменить указываемый объект каким-нибудь производным классом, вы фактически изменяете тип всей видимой клиенту комбинации. На этом основано решение проблемы оператора +=, которая требует самомодификации левого операнда, а также возможного оперативного изменения типа «на ходу». Если правый операнд Complex складывается с левым операндом Integer, тип левого операнда приходится менять.

// В файле number.h

class NBase; // Клиентам об этом ничего знать не нужно

class Number {

protected:

Number(const Number&) {}

Number() {}

public:

virtual NBase& AddTo(const NBase&) = 0;

virtual Number& operator+(const Number&) = 0;

// И т.д.

};

// В файле number.cpp

class Integer;

class Real;

class PNumber : public Number {

private:

NBase* number;

protected:

virtual NBase& AddTo(const NBase& n) const

{ return number->AddTo(n); } // #2

public:

PNumber(NBase* n) : number(n) {}

virtual Number& operator+(const Number& n) const

{

number = &(n.AddTo(*number)); // #1 - замена

return *this;

}

};

class NBase : public Number {

// Промежуточный базовый класс

// Традиционная двойная передача в NBase

public:

virtual NBase& operator+=(const Integer&) const = 0;

virtual NBase& operator+=(const Real&) const = 0;

// И т.д.

virtual NBase& AddTo(const NBase&) const = 0;

virtual Number& operator+(const Number& n) const

{ return Integer(0); } // Заглушка не вызывается

};

class Integer : public NBase {

private:

int value;

protected:

virtual NBase& operator+=(const Integer& i) const

{

if (value + i.value достаточно мало) {

value += i.value;

return *this;

}

else {

ArbitraryPrecisionInteger api(value);

api += i.value;

delete this;

return api;

}

public:

Integer(int i) : value(i) {}

virtual NBase& AddTo(const NBase& n) const

{ return n + *this; } // #3

};

class Real : public NBase { ... };

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

Это важно, поскольку в конечном счете мы хотим заменить указываемый объект левого операнда новым. Это происходит в двух местах:

1. Операторная функция PNumber::operator+=(const Number&) автоматически заменяет

число полученным новым значением.

2. Операторная функция Integer::operator+=(const Integer&) возвращает управление,

если ей не приходится изменять тип; в противном случае после удаления своего объекта она

возвращает новый объект другого типа.

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

Показанный пример надежно работает, пока PNumber действует как ведущий указатель и пока можно гарантировать, что ни один объект, производный от NBase, не будет существовать без ссылающегося на него PNumber. В нашем случае, когда все прячется в файле .cpp, дело обстоит именно так.

Для такой простой проблемы программа получилась довольно большой. Я не утверждаю, что ваши хлопоты оправдаются во всех проектах. Мое решение в основном предназначено для ситуаций, в которых вы тратите много времени на разработку иерархии классов многократного использования и можете позволить себе потратить время на повышение модульности. Я привел его, поскольку оно соответствует основной идее книги - выжать из С++ все возможное и невозможное и щедро разбросать головоломки, представляющие интерес даже для самых выдающихся экспертов.


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



Специальное предложение


Сайт визитка за 90 $
создание, разработка сайта
  • Регистрация доменного имени в зоне .net.ru или .pp.ru (1 год)
  • Хостинг (1 год)
  • Готовый дизайн
  • Поддержка РНР
  • 3 страницы сайта (главная, о фирме, контакты)
  • Регистрация в 256 поисковых системах и каталогах
  • Форма сообщений
заказать создание сайта визитки
Размещение объявлений
Недорого предлагаем разослать ваше рекламное предложение о товарах или услугах на сотни досок объявлений по всему Рунету.
размещение объявлений на электронных досках
Друзья сайта
  • Реклама - каталог ресурсов Реклама - каталог ресурсов - Реклама Карта сайта
  • Просто добавь свой сайт
  • Ипотека, коммерческая и загородная недвижимость, продажа квартир и коттеджей
  • Выставки, выставки России, Выставки Москвы, зарубежные выставки
  • Music singer R&B song
  • Язык С++
    Просматривать полку книг о С++ в книжном магазине ничуть не интереснее, чем литературу по бухгалтерии. В сущности, все книги пересказывают одно и то же и отличаются разве что по весу и количеству цветов в диаграммах и таблицах.
    Copyright студия Web-дизайна САР © 2007
    Используются технологии uCoz