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



Download 1,95 Mb.
Pdf ko'rish
bet92/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   88   89   90   91   92   93   94   95   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
161 

// 
Код, вызывающий вторичные эффекты 

void Dad::Fn1() 

// 
Код, вызывающий другие вторичные эффекты 

void AuntMartha::Fn1() 

Grandpa::Fn1(); 
// 
Прочее 

Клиент 
Grandpa
может полагаться на вторичные эффекты этого класса. Знаю, знаю, инкапсуляция и 
все такое, на вторичные эффекты полагаться никогда не следует… но давайте спустимся на землю. 
Функции, которые мы вызываем, выполняют различные действия — скажем, рисуют на экране, 
создают объекты или записывают информацию в файле. Без этих вторичных эффектов толку от них 
будет немного. Если 
Grandpa
обладает некоторыми встроенными вторичными эффектами, клиенты 
Grandpa
могут с полным правом надеяться, что эти эффекты сохранятся во всех производных классах. 
Но вот 
Dad
усомнился в авторитете 
Grandpa
и в своем переопределении 
Fn1()
не потрудился вызвать 
Grandpa::Fn1()
. Вторичные эффекты 
Grandpa::Fn1()
пропадают. Рано или поздно это начнет 
беспокоить клиента 
Grandpa
, которые, возможно, ждал от 
Dad
совсем иного. А вот 
AuntMartha
в 
свом переопеределении вызывает 
Grandpa::Fn1()
и потому сохраняет все вторичные эффекты 
Grandpa::Fn1()
. Теперь 
AuntMartha
может выполнять любые дополнительные действия в пределах 
разумного — клиентов 
Grandpa
это совершенно не интересует. 
Если переопределенная функция вызывает версию базового класса, говорят, что она нормально 
наследуется от этой функции. Не важно, где находится этот вызов — в начале, в конце или середине 
переопределенной функции. Важно лишь то, что в какой-то момент он все же происходит. Если все 
переопределенные функции производного класса наследуются нормально, говорят, что весь класс 
наследуется нормально. Если все производные классы гомоморфного базового класса наследуются 
нормально и ни один из них не обладает особо вопиющими вторичными эффектами, их можно 
подставлять вместо друг друга. 
Самый простой способ обеспечить взаимозаменяемость — сделать все функции 
Grandpa
чисто 
виртуальными. Это вырожденный случай нормального наследования; если функция базового класса 
является чисто виртуальной, то все ее вторичные эффекты (которых на самом деле нет) сохраняются по 
определению. 
Инкапсуляция производных классов 
Мы все еще не рассмотрели всех причин размещения чисто абстрактного базового класса во главе 
иерархии. Взаимозаменяемость и нормальное наследование можно обеспечить как с переменными и 
невиртуальными функциями в 
Grandpa
, так и с виртуальными функциями, которые нормально 
наследуются производными классами. Зачем настаивать, чтобы 
Grandpa
был чисто виртуальным 
базовым классом? Ответ состоит всего из одного слова: инкапсуляция. Если клиент имеет дело только с 
чисто абстрактным базовым классом, содержащим только открытые функции, он получает абсолютный 
минимум информации, необходимой для использования класса. Все остальное (в том числе и сами 
производные классы) может быть спрятано от чужих глаз в файле .cpp. 
// В файле .h 
class Grandpa { ... }; 
// В файле(-ах) .cpp 
class Dad : public Grandpa { ... }; 
class AuntMartha : public Grandpa { ... }; 
Инкапсуляция производных классов — одно из редких проявлений истинного просветления 
программиста; верный признак того, что автор программы хорошо разбирается в том, что он делает. 


 162 
Чтобы усилить эффект, закрытые классы можно объявить статистическими и тем самым ограничить их 
пространтсво имен исходным файлом, в котором они находятся. 
С инкапсулированными производными классами связаны определенные проблемы. Например, как 
создать экземпляры таких классов, как 
Dad
, которые не видны клиенту из файла .h? Эти проблемы 
легко решаются с помощью идиом, описанных в двух следующих главах. А пока мы продолжим 
публиковать производные классы в файле .h, зная, что существует возможность их полной 
инкапсуляции. 
Множественная передача 
Самый распространенный пример гомоморфной иерархии — набор классов, соответствующих 
различным видам чисел: целым, комплексным, вещественным и т.д. Класс-предок такой иерархии 
может называться 
Number
и иметь интерфейс следующего вида: 
class Number { 
public: 
virtual Number operator+(const Number&) = 0; 
virtual Number operator-(const Number&) = 0; 
// 
И т.д. 
}; 
class Integer : public Number { 
private: 
int 
i; 
public: 
Integer(int x) : i(x) {} 
virtual Number operator+(const Number&); 
// 
И т.д. 
}; 
На 
бумаге 
все 
выглядит 
проще, 
чем 
в 
действительности. 
Как 
реализовать 
Integer::operator+(Number&)
, если нам не известно, что в скобках находится вовсе не 
Number
, а 
некоторый производный класс? Для каждой пары типов, участвующих в сложении, существует свой 
алгоритм. Суммирование 
Complex + Integer
отличается от 
Integer + Real
, которое, в свою 
очередь, отличается от 
Integer + ArbitraryPrecisionNumber
. Как программе разобраться, какой 
из алгоритмов следует использовать? Что-что? Кто сказал: «Запросить у аргумента оператора + его 
настоящий тип»? Немедленно встаньте в угол. 
class Number { 
protected: 
int 
type; 
// 
Хранит информацию о настоящем типе 
int TypeOf() { return type; } 
// 
И т.д. 
}; 
// Где-то в программе 
switch (type) { 
case kInteger: ... 
case kComplex: ... 

Именно этого знания типов мы постараемся избежать. Кроме того, все прямые реализации подобных 
схем не отличаются особой элегантностью. Вы когда-нибудь видели код, генерируемый компилятором 
для конструкции 
switch/case
? Ни красоты, ни эффективности. Вместо этого мы объединим знания 
компилятора о типах с чудесами современной технологии — v-таблицами. 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   88   89   90   91   92   93   94   95   ...   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