Материалы книги получены с http://www.itlibitum.ru/
Маскировка указываемого объекта
Поначалу кажется, что реально мы ничего не добились. Чтобы подставляемые функции работали, интерфейс класса Foo все равно должен находиться в файле .h перед объявлением класса PFoo. Тем не менее, смирившись с небольшими дополнительными вычислениями для наших указателей, мы получаем быстрый и ощутимый результат.
class Foo1; // Все, что клиент видит и знает о Foo
class PFoo1 {
private:
Foo1* foo;
public:
PFoo1();
PFoo1(const PFoo1& pf);
~PFoo();
PFoo1& operator=(const PFoo1& pf);
void DoSomething();
void DoSomethingElse();
};
class Foo1 {
friend class PFoo1;
protected:
Foo1();
public:
void DoSomething();
void DoSomethingElse();
};
PFoo1::PFoo1() : foo(new Foo1)
{}
PFoo1::PFoo(const PFoo1& pf) : foo(new Foo1(*(pf.foo)))
{}
PFoo1::~PFoo()
{
delete foo;
}
PFoo1& PFoo1::operator=(const PFoo1& pf)
{
if (this != &pf) {
delete foo;
foo = new Foo1(*(pf.foo));
}
return *this;
}
void PFoo1::DoSomething()
{
foo->DoSomething();
}
void PFoo1::DoSomethingElse()
{
foo->DoSomethingElse();
}
Foo1::Foo1()
{
}
void Foo1::DoSomething()
{
cout << "Foo::DoSomething()" << endl;
}
void Foo1::DoSomethingElse()
{
cout << "Foo::DoSomethingElse()" << endl;
}
Видите, что здесь происходит? Для клиента класс Foo перестает существовать. Для всех практических целей указатель стал самим объектом. С таким же успехом мы могли все переименовать, убрать Р перед указателем и заменить имя Foo чем-ни6удь более закрытым и загадочным. Единственное, что говорит о существовании второго класса, - предварительное объявление class Foo;. Цена всего происходящего - вызов не подставляемых (noninline) функций в каждой функции класса указателя. Для некоторых немногочисленных приложений и классов даже эта малая цена может стать неприемлемой. В таких случаях существуют две альтернативы для повышения скорости:
использование умных указателей на базе оператора -> и использование интерфейсных указателей с занесением объявления класса указываемого объекта в файл .h и отказом от всех преимуществ инкапсуляции. Как вы убедитесь в оставшейся части этой главы, второй вариант все же имеет некоторые достоинства.
Назад Содержание Далее
|