TheLogicGuy
TheLogicGuy

Reputation: 691

Can't override operator delete/new from pure abstract class in C++

I want to override new and delete operators of a class to make it use my memory pool.
It works with normal classes (no inheritance) but I fail to do that with classes which inherit from an abstract base class.

Name of the abstract base class: MemTester
Name of the concrete class which derives from MemTester: BasicTester

Here are the files (2 headers for each class and 2 CPP files for each class)

Here is the abstract base class:

class MemTester {
public:
    virtual void test() = 0;
    virtual ~MemTester() {}
    void* operator new(size_t sz);
    void * operator new[](size_t sz);
    void operator delete(void* ptr) noexcept;
    void operator delete[](void* ptr) noexcept;
};

Here is the CPP file of the above header:

#include "..//headers//MemTester.h"
#include "..//headers//MemoryManager.h"

void * MemTester::operator new(size_t sz)
{
    return (void*)MemoryManager::allocate(sz);
}

void * MemTester::operator new[](size_t sz)
{
    return (void*)MemoryManager::allocateArr(sz);
}

void MemTester::operator delete(void * ptr) noexcept
{
    MemoryManager::free((char*)ptr);
}

void MemTester::operator delete[](void * ptr) noexcept
{
    MemoryManager::freeArr((char*)ptr);
}

And here is a header of a derived class which derived from the above base class:

#include "MemTester.h"
#include <cstddef>

class BasicTester : public MemTester {
public:
    void test();
    void* operator new(size_t sz);
    void operator delete(void* ptr) noexcept;
private:
    void test1();
};

And it's CPP file:

#include "..//headers//BasicTester.h"
#include "..//headers//MemoryManager.h"
#include <iostream>

void BasicTester::test()
{
    test1();
}

void BasicTester::test1()
{
    std::cout << "====== Basic test 1 ======\n" << std::endl;
}

void * BasicTester::operator new(size_t sz)
{
    return (void*)MemoryManager::allocate(sz);
}

void BasicTester::operator delete(void * ptr) noexcept
{
    MemoryManager::free((char*)ptr);
}

The problem:

When I call:

MemTester* mt = new BasicTester();

It calls why overriden operator new as expected. But when I call

delete mt;

It calls the default operator delete
But if I write: MemTester::operator delete(mt); It calls the overriden op delete;
I don't understand why simply calling delete p when p is a pointer to a class without inheritance calling my op delete. But when I use a derived class I've to write ClassName::operator delete (p)

Upvotes: 0

Views: 265

Answers (1)

user3458
user3458

Reputation:

Update: According to http://en.cppreference.com/w/cpp/language/delete :

The deallocation function's name is looked up in the scope of the dynamic type of the object pointed to by expression, which means class-specific deallocation functions, if present, are found before the global ones. If :: is present in the delete expression, only the global namespace is examined by this lookup.

(emphasis mine)

This is wrong: The operator delete used is based on the type of the pointer that's being deleted, not on the type of the object the pointer points to.

Upvotes: 0

Related Questions