Сущность технологии СОМ. Библиотека программиста | страница 26



не сможет динамически найти последний порожденный деструктор и рекурсивно уничтожит объект ближайшего внешнего типа по отношению к базовому типу. Поскольку деструктор FastString никогда не вызывается, в данном примере из буфера исчезнет строка «Deface me», которая должна там присутствовать.

Очевидное решение этой проблемы – сделать деструктор виртуальным в классе интерфейса. К сожалению, это нарушит независимость класса интерфейса от транслятора, так как положение виртуального деструктора в таблице vtbl может изменяться от транслятора к транслятору. Одним из конструктивных решений этой проблемы является добавление к интерфейсу явного метода Delete как еще одной чисто виртуальной функции, чтобы заставить производный класс уничтожать самого себя в своей реализации этого метода. В результате этого будет выполнен нужный деструктор. Модифицированная версия заголовочного файла интерфейса выглядит так:


// ifaststring.h

class IFastString

{

public:

virtual void Delete(void) = 0;

virtual int Length(void) const = 0;

virtual int Find(const char *psz) const = 0;

};

extern "C"

IFastString *CreateFastString (const char *psz);


она влечет за собой соответствующее определение класса реализации:


// faststring.h

#include «ifaststring.h»

class FastString : public IFastString

{ const int mcch;

// count of characters

// счетчик символов

char *mpsz; public: FastString(const char *psz);

~FastString(void);

void Delete(void);

// deletes this instance

// уничтожает этот экземпляр

int Length(void) const;

// returns # of characters

// возвращает число символов

int Find(const char *psz) const;

// returns offset

// возвращает смещение

};

// faststring.cpp

#include

#include «faststring.h»

IFastString* CreateFastString (const char *psz) {

return new FastString(psz);

}

FastString::FastString(const char *psz) : mcch(strlen(psz)), mpsz(new char[mcch + 1]) {

strcpy(mpsz, psz);

}

void FastString::Delete(void) {

delete this;

}

FastString::~FastString(void) {

delete[] mpsz;

}

int FastString::Lengtn(void) const {

return mcch;

}

int FastString::Find(const char *psz) const {

// O(1) lookup code deleted for clarity

// код поиска 0(1) уничтожен для ясности

}

Рисунок 1.7 показывает представление FastString на этапе выполнения. Чтобы использовать тип данных FastString, клиентам надо просто включить в программу файл определения интерфейса и вызвать CreateFastString:

#include «ifaststring.h»

int f(void)

{ int n = -1;

IFastString *pfs = CreateFastString(«Hi Bob!»);