Overriding the new / delete operator in a derived class

I have an abstract, abstract base class from which various concrete classes are inherited. Some of these derived classes are also stateless. Since many of them are created during the run, I would like to save memory and overhead due to the fact that all derived classes without apathy emulate a singleton by overriding the new () / delete () operator. A simplified example would look something like this:

#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; } 

This example does not work: delete s2; fails because delete s1; called ~Base() , which freed up generic Base in d2 . This can be fixed by adding the same trick with new / remote overloading to Base. But I'm not sure if this is the cleanest solution, or even the right one (valgrind doesn't complain, FWIW). I would appreciate advice or criticism.

edit: the situation is actually worse. The base class in this example is not abstract, as I claimed. If he made it abstract by adding a pure virtual method, I can no longer apply the new / remove overriding trick, because I cannot have a static variable of type Base. Therefore, I have no solution for this problem!

+6
source share
2 answers

I would say that the best solution here is to make your derived class a real single. Make your derived constructor private and just provide the static Base * getInstance () method, which either creates the required object or returns a static instance. Thus, the only way to get the D1 object will be this method, since calling a new D1 will be illegal.

+1
source

You simply cannot do this - this will violate the requirement of "object identity", which states that each object must have its own address . You must allocate a separate memory block for each object - this can be done quite quickly if you redefine operator new to use a fast allocator block specifically designed for objects of a fixed size.

+2
source

Source: https://habr.com/ru/post/891075/


All Articles