У меня есть абстрактный класс без сохранения состояния, от которого наследуются различные конкретные классы. Некоторые из этих производных классов также не имеют состояния. Поскольку многие из них создаются во время выполнения, я бы хотел сэкономить память и накладные расходы, поскольку все производные классы без сохранения состояния эмулируют одноэлементный, переопределяя оператор new () / delete (). Упрощенный пример будет выглядеть примерно так:
#include <memory>
struct Base {
virtual ~Base() {}
protected:
Base() {} // prevent concrete Base objects
};
struct D1 : public Base { // stateful object--default behavior
int dummy;
};
struct D2 : public Base { // stateless object--don't allocate memory
void* operator new(size_t size)
{
static D2 d2;
return &d2;
}
void operator delete(void *p) {}
};
int main() {
Base* p1 = new D1();
Base* p2 = new D1();
Base* s1 = new D2();
Base* s2 = new D2();
delete p1;
delete p2;
delete s1;
delete s2;
return 0;
}
Этот пример не работает: delete s2;
не удается, потому что delete s1;
вызвал ~Base()
, что освободило общий Base
в d2
. Эту проблему можно решить, добавив тот же трюк с перегрузкой new / delete в Base. Но я не уверен, что это самое чистое или даже правильное решение (valgrind не жалуется, FWIW). Буду признателен за совет или критику.
edit: на самом деле, ситуация хуже. Базовый класс в этом примере не является абстрактным, как я утверждал. Если это сделано абстрактно, посредством добавления чисто виртуального метода, то я больше не могу применять трюк переопределения new / delete, потому что у меня не может быть статической переменной типа Base. Поэтому у меня нет решения этой проблемы!