Re[9]: virtual base class для чего обычно юзается?
От: Андрей Тарасевич Беларусь  
Дата: 21.01.02 07:50
Оценка: 178 (26) +1
Здравствуйте Sashko, Вы писали:

S>Может не поверишь, Игорь, но иногда небольшой смысл есть ;). С virtual наследованием (хотя эта вещь закладывалась как раз для полиморфного наследования) можно делать вот такую вещь


S>При виртуальном наследовании, в конструкторе наследника (любого уровня) мы должны указывать как инициализируется базовый виртуальный класс. Если в списке инициализации конструктора наследника, явно не указан конструктор базового виртуального класса, то будет использоваться конструктор по умолчанию (если такового нет, то компилятор выдаст ошибку). Таким образом, в наследнике любого уровня, легко можно проинициализировать базовый класс (в TurboVision было похожее использование виртуального наследования). Не спорю, что, то же самое можно сделать и без виртуального наследования, удобно это или нет, решать самому.


На этом принципе основан также родственный трюк, позволяющий обозначать определенные классы как финальные, т.е. как классы, от которых нельзя наследовать:

class VB
{
  friend class CFinal;

private:
  VB() {}
};

// Пример финального класса
class CFinal : private virtual VB 
{
};


В данном примере от класса 'CFinal' нельзя унаследовать никакие другие классы. Если попытаться это сделать, то на класс-наследник будет возложена обязанность констуирования виртуальной базы 'VB'. А он этого сделать не может, т.к. не имеет доступа к конструктору класса 'VB'.

Этот прием можно оформить более универсально через шаблоны:

template <class T_> 
class CInheritanceStopper
{
  friend class T_;

private:
  CInheritanceStopper() {}
};

////////////////////////////////////
// Пример финального класса

class CFinal : private virtual CInheritanceStopper<CFinal>
{
};


Или еще более элегантный вариант:

template <class T_> class CInheritanceStopper; 

template <class T_> 
class CInheritanceStopper_
{
  friend class T_;
  friend class CInheritanceStopper<T_>;

private:
  CInheritanceStopper_() {}
};

template <class T_> 
class CInheritanceStopper : private virtual CInheritanceStopper_<T_> {};

////////////////////////////////////
// Пример финального класса

class CFinal : CInheritanceStopper<CFinal>
{
};
Best regards,
Андрей Тарасевич
http://files.rsdn.org/2174/val.gif
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.