Ознакомьтесь с нашей политикой обработки персональных данных
  • ↓
  • ↑
  • ⇑
 
Записи с темой: трюки с наследованием (список заголовков)
10:44 

Трюк 0x000D — Рекурсивное наследование

mistificator
капелюх чарiвника
Практическая польза от данного трюка определённо должна быть. Как придумаете, как его использовать — сообщайте.


//------------------------------------------------------------
#include
using namespace std;

class A {
public:
A() {
cout << "ctor A" << endl;
}
virtual void foo() {
cout << "foo A" << endl;
}
};

template
class B: public T {
public:
B(): T() {
cout << "ctor B<" << typeid(T).name() << ">" << endl;
}
virtual void foo() {
cout << "foo B<" << typeid(T).name() << ">" << endl;
}
};

int main() {

A * a = new B < B < B < B < B < A > > > > > ( );
a->foo();

return 0;
}
//------------------------------------------------------------

@темы: Трюки с наследованием, Трюки с шаблонами

23:47 

Трюк 0x0009 — Deep Private

Куб 0
Иногда разработчику класса нужно скрыть от пользователя некоторые особенности реализации интерфейса. Речь идет о секции private, в которой обычно размещаются переменные класса и методы, предназначенные сугубо для внутреннего использования. Пользователю вовсе необязательно видеть секцию private, особенно, если реализация класса находится внутри скомпилированной библиотеки .dll, а в руках пользователя лишь заголовочный файл.
Читать далее...

@темы: .DLL, Трюки с наследованием

16:32 

Трюк 0x0008 — Never too late

Куб 0
В устоявшуюся терминологию программистов C++ входят понятие раннего связывания (на стадии компиляции) и понятие позднего, отложенного связывания (динамически, во время исполнения). Далее в статье будет предложено решение для не просто позднего, а по-настоящему запоздалого связывания данных. Представьте, что Вы можете выбирать обработчик для данных прямо во время выполнения программы и, более того, ассоциировать с данными несколько обработчиков. Представьте, что при этом работает полиморфизм. Представьте, что если Вам более не нужны выдаваемые объектом данные, Вы можете "отключиться" от объекта, как клиент от сервера.
Как такое реализовать?
Читать далее...

@темы: Нетривиальный вызов, Трюки с наследованием, Трюки с шаблонами, Философия

00:20 

Трюк 0x0007 — Узнаем, сколько создано объектов

Куб 0
В программе, изобилующей мелкими объектами, иногда необходимо выяснить, сколько именно объектов создано, сотня или же миллион. А если объекты создаются и уничтожаются постоянно в течение жизненного цикла программы, то зачастую интересует вопрос, сколько раз были созданы объекты того или иного типа?
Ключевые элементы такого счетчика объектов вырисовываются сразу: некие глобальные переменные и привязка к типам объектов.
Сразу хочется сказать о подводных камнях, которые обнаруживаются в процессе организации счетчика. Дело в том, что классы как правило имеют наследование, поэтому простое инкрементирование счетчика в каждом конструкторе никуда не годится — при вызове конструктора будут инкрементированы и счетчики всех базовых классов.
В приведенной далее реализации счетчика объектов используется соглашение, что базовый класс отмечается разработчиком. Для различения счетчиков разных объектов используется шаблонный класс, который специфицируется типом. (Возможно, альтернативным более компактным решением было бы специфицирование шаблона строкой, получаемой из typeid при подстановке this.) Счетчик, установленный в каком либо классе, обязательно должен быть установлен и во всех его производных классах, если только Вы не хотите, чтобы объекты производных классов подсчитывались в одной куче с объектами базовых классов.
Читать дальше...

Thread-safe оптимизированный вариант счетчика, предложенный моим коллегой, сопряжен с использованием множественного наследования, и содержит три класса. Однако прост для понимания, и категорически рекомендован к использованию.
Читать дальше...

@темы: Счётчики объектов, Трюки с наследованием

16:01 

Трюк 0x0003 — К слову о синглетонах

Куб 0
Классический синглетон — класс-одиночка — представляет собой класс, объект которого может быть создан один единственный раз за весь период выполнения программы, и который существует в течение всего времени выполнения программы. Реализовать его можно разными способами, о которых можно прочитать в литературных трудах Банды Четырех и ставшего притчей во языцех Коплиена.
Однако, наиболее компактным, и не вызывающим головной боли при эксплуатации, является приведенный ниже вариант.
Читать дальше...


Другим подходом к созданию синглетона является использование шаблона.
Читать дальше...

@темы: Паттерны, Трюки с наследованием

17:47 

Трюк 0x0000 — Избегание наследования

Куб 0
Как поступить, если под рукой имеется абстрактный класс, функциональность которого хочется задействовать, но наследовать свой класс от него неохота?
Пусть имеется абстрактный класс окна AbstractWindow с чисто виртуальным методом Create().

//------------------------------------------------------------
class AbstractWindow {
public:
AbstractWindow() {
// код конструктора
}
virtual ~AbstractWindow() {
// код деструктора
}

virtual int Create(const char *Title)=0 {
// общий код создания окна
}
};
//------------------------------------------------------------
Предположим, что некий класс SimpleApplication, являющийся базовым классом для простых приложений, должен вызывать функцию создания окна. Таким образом, он должен включать в себя функциональность AbstractWindow. Открытое или закрытое наследование здесь нежелательно, так как логически SimpleApplication не связан с AbstractWindow — приложение не является частным случаем окна.
Злоупотребляя механизмом наследования, можно создать производный от AbstractWindow производный класс SimpleWindow, имеющий в своем методе Create() весь необходимый арсенал для создания окна. Тогда экземпляр SimpleWindow можно было бы включить в интерфейс SimpleApplication и вызвать Create() в подходящий момент. Однако что, если для класса ComplexApplication, производного от SimpleApplication, понадобится новая реализация метода создания окна? Следует ли тогда создать производный класс ComplexWindow, открывая таким образом разработчику единственный путь — создание новых подклассов по мере создания новых видов приложений? Читать дальше...

@темы: Трюки с наследованием

Записная книжка программиста C++

главная