C++: библиотека программиста



Download 1,95 Mb.
Pdf ko'rish
bet63/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   59   60   61   62   63   64   65   66   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
103 
Проверка граней 
Давайте еще немного расширим эту идиому и предположим, что некоторая грань может 
поддерживаться или не поддерживаться объектом. О том, почему и как это может произойти, мы 
поговорим во время изучения переходных типов далее в этой главе, а пока ответим на вопрос: как 
клиент может определить, поддерживается ли некоторый объект некоторой гранью? Решение 
построено на другом С++-изме — перегрузке оператора 
!

class ViewEvents { 
private: 
View* 
view; 
public: 
ViewEvents(View* v) : view(v) {} 
bool operator!() { return view == NULL; } 
// 
И т.д. 
}; 
// В клиентском коде 
ViewEvents ve(aViewGemstone); 
if (!ve) { 
cerr << “Вид не обрабатывает событий!” << endl; 
throw 
interface_error; 

Предполагается, что 
aViewGemstone
относится к кристаллам вида, о которых говорилось выше, и 
содержит операторную функцию 
operator ViewEvents()
. Ключевая строка 
ViewEvents
ve(aViewGenistone)
работает в два этапа: сначала вызывается операторная функция operator 
ViewEvents()
, выполняющая преобразование, а затем ve конструируется с помощью конструктора 
копий 
ViewEvents
. Если кристалл вида решает, что данный вид не обрабатывает событий, он может 
сконструировать экземпляр 
ViewEvents
с 
view
, равным 
NULL
. Затем оператор 
!
проверяет 
возвращенную грань. Функции грани также могут проверять наличие объекта перед тем, как пытаться 
что-то делегировать ему. 
Void ViewEvents::DoSomething() 

if 
(!*this) 
// 
то есть if (view == NULL) 
// 
Инициировать исключение 
view->DoSomething(); 

Обеспечение согласованности 
В одних отношениях C++ непроницаем, как гранитная скала, в других — дыряв, как решето. Одна из 
таких дыр — несогласованный подход к преобразованию типов. Вы можете получить адрес 
переменной класса, но по этому адресу нельзя безопасно перейти к объекту, которому принадлежит 
переменная. У компилятора хватает ума для автоматического приведения указателя на производный 
класс к указателю на базовый, но вернуться к указателю на производный класс он уже не сможет. 
Придется выполнять небезопасное явное преобразование, пользующееся дурной славой. Большинство 
программистов и проектировщиков лишь испускает глубокий вздох, обычно приберегаемый для 
супружеских ссор, и живет с этими несоответствиями. Однако благодаря идиоме граней открывается 
уникальная возможность «исправить» этот аспект C++. Существуют три свойства, которые в со-
вокупности обеспечивают отсутствующую в C++ степень согласованности. В следующем описании 
выражение 
а=>b
означает, что грани типа А содержат оператор преобразования, дающий грань типа B; 
а и b являются конкретными экземплярами типов А и В соответственно. Хотя эти правила относятся к 
специфике C++ и граней, они также являются частью стандартной дисциплины проектирования, 
используемой в технологии СОМ компании Microsoft: 


 104 
1. Симметричность. Если а=>b, то b=>а. Последствия: грань — переменная класса должна уметь 
восстанавливать вмещающий объект, из которого она получена, а грань — базовый класс 
должна уметь безопасно «возвращаться» к правильному производному классу. 
2. Транзитивность. Если а=>b, а=>с и b=>c2, то с и с2 должны быть эквивалентны; точнее, они 
должны быть гранями одного объекта, обеспечивающими идентичные наборы функциональных 
средств. При этом физически они могут быть разными гранями. 
3. Устойчивость граней. Пока грань существует, она должна работать корректно. Иначе говоря, 
при удалении указываемого объекта все ссылающиеся на него грани после выполнения 
оператора 
!
начинают возвращать 
false
и инициировать исключения при вызове функций. Это 
положение можно было бы сформулировать и более строго — указываемый объект не должен 
уничтожаться до тех пор, пока для него существует хотя бы одна грань. В частности, это 
правило используется в технологии СОМ. 
Первые два правила выполнить несложно, хотя за это нередко приходится расплачиваться объемом и 
быстродействием. Посидите пару вечеров, набейте живот жирной пиццей, и вы наверняка сами 
придумаете, как обеспечить выполнение этих двух правил. Некоторые рекомендации приведены ниже. 
Устойчивость граней — совсем другое дело; мы констатируем проблему сейчас, но откладываем 
решение до следующих глав. 
Симметричность 
Самый простой способ выполнить это требование — включить в класс грани две переменные. В одной 
хранить адрес составного объекта, используемого гранью, а в другой — адрес кристалла или исходного 
указываемого объекта. 
class BarFacet { 
private: 
Bar* 
bar; 
PointeeGemstone* 
gemstone; 
public: 
BarFacet(Bar* b, PointeeGemstone* agg) : bar(b), gemstone(agg) {} 
operator PointeeGemstone() { return *gemstone; } 
// 
Интерфейсы к функциям Bar 
}; 
Наличие обратного указателя обеспечивает симметричность; по кристаллу можно .получить грань, а по 
грани — кристалл. Основная проблема состоит в том, что 
BarFacet
не годится для повторного 
использования, если Ваг является компонентом различных кристаллов; для каждого использования 
приходится создавать отдельную грань. 
Транзитивность 
На самом деле соблюдение этого принципа зависит от дисциплины проектирования. Транзитивность 
нарушается в ситуациях наподобие следующей: 
class Foo { 
private: 
Blob* 
blob; 
Bar* 
bar; 
}; 
class Bar { 
private: 
Blob* 
another_blob; 
}; 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   59   60   61   62   63   64   65   66   ...   144




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish