Re[15]: Перегрузка операторов
От: Red Line  
Дата: 25.05.04 10:36
Оценка:
Здравствуйте, adontz, Вы писали:

A> . . .


По поводу прочитанных книг:
Да действительно те книги которые прочитал буквально вскользь затрагивали тему этой дискуссии.
Сейчас по почте закаказал книгу Страуструпа, буду грызть его
Весь смысл задаваемых мной вопросов сводится к пониманию следующего кода:
(из книги Дейла Роджерсона "Основы технологии COM").
Я одолел 8 глав, на девятой застрял потому-что не смог понять материал по теме "перегрузка операторов"
Тогда и решил на Ваш форум обратиться... Впрчем вот эта глава...


Реализация класса указателя на интерфейс

Хотя классов smart-указателей для работы с интерфейсами СОМ и не так много, как классов строк, но число тех и
других не сильно различается. ActiveX Template Library (ATL) содержит классы указателей на интерфейсы СОМ
CComPtr и CComQIPtr. В библиотеке MFC имеется класс CIP для внутреннего пользования. (Он находится в
файле AFXCOM_.H.) CIP — это самый полный вариант класса smart-указателя на интерфейс. Он делает
практически все. Здесь я представлю свой собственный, главным образом потому, что мой код легче читается.
Мой класс похож на классы из ATL и MFC, но не столь полон.
----------------------------------------------
* Точнее, для указателя CFoo*. — Прим. перев.
** Функция operator-> означает не «разыменуй меня», а «используй меня для обращения к моим методам или переменным-членам» — Прим..
перев.
----------------------------------------------
Клиент вызывает члены интерфейса напрямую с помощью operator->
Доступ к функциям-членам класса smart-указателя осуществляется с использованием нотации "точка"
Мой класс указателя на интерфейс называется IPtr и реализован в файле PTR.H, который представлен в листинге
Пусть длина исходного текста Вас не пугает. Кода там очень мало. Я просто вставил побольше пустых строк,
чтобы легче было читать.


Шаблон IPtr из PTR.H
//
// IPtr – Smart-указатель на интерфейс
// Использование: IPtr<IX, &IID_IX> spIX;
// Не используйте с IUnknown; IPtr<IUnknown, &IID_IUnknown>
// не будет компилироваться. Вместо этого используйте IUnknownPtr.
//
template <class T, const IID* piid> class IPtr
{
public:
// Конструкторы
IPtr()
{
m_pI = NULL;
}
IPtr(T* lp)
{
m_pI = lp;
if (m_pI != NULL)
{
m_pI->AddRef();
}
}
IPtr(IUnknown* pI)
{
m_pI = NULL;
if (pI != NULL)
{
pI->QueryInterface(*piid, (void **)&m_pI);
}
}
// Деструктор
~IPtr()
{
Release();
}
// Сброс в NULL
void Release()
140
{
if (m_pI != NULL)
{
T* pOld = m_pI;
m_pI = NULL;
pOld->Release();
}
}
// Преобразование
operator T*() { return m_pI; }
// Операции с указателем
T& operator*() { assert(m_pI != NULL); return *m_pI; }
T** operator&() { assert(m_pI == NULL); return &m_pI; }
T* operator->() { assert(m_pI != NULL); return m_pI; }
// Присваивание того же интерфейса
T* operator=(T* pI)
{
if (m_pI != pI)
{
IUnknown* pOld = m_pI; // Сохранить старое значение
m_pI = pI; // Присвоить новое значение
if (m_pI != NULL)
{

m_pI->AddRef();
}
if (pOld != NULL)
{
pOld->Release(); // Освободить старый интерфейс
}
}
return m_pI;
}
// Присваивание другого интерфейса
T* operator=(IUnknown* pI)
{
IUnknown* pOld = m_pI; // Сохранить текущее значение
m_pI == NULL ;
// Запросить соответствующий интерфейс
if (pI != NULL)
{
HRESULT hr = pI->QueryInterface(*piid, (void**)&m_pI);
assert(SUCCEEDED(hr) && (m_pI != NULL));
}
if (pOld != NULL)
{
pOld->Release(); // Освободить старый указатель
}
return m_pI;
}
// Логические функции
BOOL operator!() { return (m_pI == NULL) ? TRUE : FALSE; }
// Требует компилятора, поддерживающего BOOL
operator BOOL() const
{
return (m_pI != NULL) ? TRUE : FALSE;
}
// GUID
const IID& iid() { return *piid; }
private:
// Хранимый указатель
141
T* m_pI;
};


Разборки вырезаны. -- ПК
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.