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



Download 1,95 Mb.
Pdf ko'rish
bet104/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   100   101   102   103   104   105   106   107   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
185 
Удвоенная двойная передача 
Итак, давайте попробуем реализовать двойную передачу для невидимых указателей. Этот раздел 
представляет собой элементарное распространение приемов, которыми мы пользовались без связи с 
указателями. 
Первая попытка 
Сейчас мы сделаем первый заход на арифметические операции с невидимыми указателями. Он 
работает, но обладает некоторыми ограничениями, на которые следует обратить внимание и должным 
образом исправить. Чтобы избежать проблем, связанных с возвращением ссылок на временные 
значения (см. окончание главы 11), я перехожу на использование оператора 
new
. Проблемы сборки 
мусора будут рассматриваться позже. 
// В файле number.h 
class NBase; // Клиентам об этом ничего знать не нужно 
class Number { 
protected: 
Number(const Number&) {} 
Number() 
{} 
public: 
virtual NBase& operator+(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& operator+(const NBase& n) const 
{ return *number + n; } 
// #2 
public: 
PNumber(NBase* n) : number(n) {} 
virtual Number& operator+(const Number& n) const 
{ return *(new PNumber(&(n + *number))); } 
// #1 
}; 
class NBase : public Number { 
// Промежуточный базовый класс 
// Традиционная двойная передача в NBase 
public: 
virtual NBase& operator+(const Integer&) const = 0; 
virtual NBase& operator+(const Real&) const = 0; 
// 
И т.д. 
virtual NBase& operator+(const NBase&) const = 0; 
virtual Number& operator+(const Number& n) const 
{ return Integer(0); } 
// Заглушка не вызывается 
}; 
class Integer : public NBase { 


 186 
private: 
int 
value; 
protected: 
virtual NBase& operator+(const Integer& i) const 
{ return *(new Integer(value + i.value)); } // #4 
public: 
Integer(int i) : value(i) {} 
virtual NBase& operator+(const NBase& n) const 
{ return n + *this; } 
// 
#3 
}; 
class Real : public NBase { ... }; 
Как и в исходном варианте двойной передачи, постарайтесь не сосредотачивать взгляд и медленно 
отодвигайте страницу от носа, пока ну ловите суть происходящего. Ниже подробно расписано, что 
происходит, когда клиент пытается сложить два 
Number
(а на самом деле — два 
PNumber
, но клиент об 
этом не знает). Предположим, складываются два 
Integer

1. Вызывается операторная функция 
PNumber::operator+(const Number&)
левого указателя. 
Выражение переворачивается, и вызывается аналогичная функция правого указателя, при этом 
аргументом является левый указываемый объект. Однако перед тем, как это случается, функция 
создает 
PNumber
для результата. 
2. Вызывается операторная функция 
PNumber::operator+(const NBase&)
левого указателя. 
Вызов делегируется оператору 
+
указываемого объекта. 
3. Вызывается операторная функция 
Integer::operator+(const NBase&)
правого 
указываемого объекта. Выражение снова переворачивается. 
4. Вызывается операторная функция 
Integer::opeator+(const Integer&)
левого 
указываемого объекта, где наконец и выполняется реальная операция вычисления суммы. 
В итоге происходит четыре передачи — две для указателей и две для указываемых объектов. Отсюда и 
название — удвоенная двойная передача. Мы обходимся без преобразований типов, но зато о 
существовании 
NBase
приходится объявлять на первых страницах газет. 
Сокращение до трех передач 
Если мы разрешим программе «знать», что изначально слева и справа стоят 
PNumber
, и выполним 
соответствующее приведение типов, количество передач можно сократить до трех: оставить одну 
передачу для операторной функции 
PNumber::operator+(const Number&)
плюс две обычные 
двойные передачи. Первый 
PNumber
приходит к выводу, что справа также стоит 
PNumber
, выполняет 
понижающее преобразование от 
Number
к 
PNumber
, а затем напрямую обращается к указываемому 
объекту. При этом удается обойтись без 
PNumber::operator+(const NBase&)
. Есть и 
дополнительное преимущество — при должной осторожности можно удалить из файла .h все ссылки 
на NBase. 
Проблема заключается в том, что какой-нибудь идиот может вопреки всем предупреждениям породить 
от 
Number
свой класс, выходящий за пределы вашей тщательно построенной иерархии. Это будет 
означать, что не все 
Number
будут обязательно «запакованы» в 
PNumber
. Только что показанная 
методика предотвращает создание производных от 
Number
классов за пределами файла .cpp и даже 
правильно работает с производными классами без оболочек (
Number
без 
PNumber
) при условии, что 
они правильно реализуют схему удвоенной двойной передачи. 
Как долго результат остается действительным? 
В показанной выше реализации клиент должен помнить о необходимости избавляться от 
Number

вызывая 
delete &aResult
. Это серьезное ограничение среди прочего усложняет вложенные 
вычисления, поскольку для всех промежуточных результатов приходится создавать указатель для их 
последующего удаления. В комитет ANSI поступило предложение (так и не принятое), в соответствии 
с которым компилятор должен гарантировать, что временная величина в стеке остается действительной 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   100   101   102   103   104   105   106   107   ...   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