2

I don't understand why I am getting compiler errors when trying to compile this:

void* MemoryManagedObject::operator new(size_t size, bool UseMemPool)
{
    Engine* engine = Engine::GetEngine();
    void* alloc;

    alloc = engine->GetMemoryManager()->Allocate(size, UseMemPool);

    if (alloc && UseMemPool)
        mAllocatedWithMemPool = true;

    return alloc;
}

It says "invalid use of member MemoryManagedObject::mAllocatedWithMemPool in static member function".

Basically, I have a flag that states whether I used my memory pool or just malloc() when allocating the class instance, and I want to set it when I override 'new'.

I guess the 'new' method must return before you can use the class instance? Is there any way around this?

EDIT: Just curious, ss this code a valid solution as well?

void* MemoryManagedObject::operator new(size_t size, bool UseMemPool)
{
    Engine* engine = Engine::GetEngine();
    MemoryManagedObject* alloc;

    alloc = (MemoryManagedObject*)engine->GetMemoryManager()->Allocate(size, UseMemPool);

    if (alloc && UseMemPool)
        alloc->mAllocatedWithMemPool = true;

    return alloc;
}
KaiserJohaan
  • 9,028
  • 20
  • 112
  • 199
  • Well, to answer your direct question: you get a compiler error because `operator new` is a static function. – Oliver Charlesworth Jan 01 '12 at 16:46
  • It's not that the `new` method must return, it's that the class instance must *exist*. It sounds like you don't want an `operator new` but a wrapper class. – David Schwartz Jan 01 '12 at 16:47
  • The allocator should allocate memory, and not construct any objects. Thus it should return a `void*`, and you can't have an access like `alloc->mAllocatedWithMemPool`. The constructor of the object will be invoked later on the memory that you return. – Kerrek SB Jan 04 '12 at 20:43

2 Answers2

3

This error basically tells you that you can't use a member of your class in a static method.
The member variable is linked with the instance which holds it (your "this" pointer). static method is not associated with a instance of your class (which makes it "static". It belongs to all the instances of yoir class.)
When you try to use a member variable in a static method, the compiler cannot know to which instance of your class this member variable belongs to, because the method belongs to all of them.

Idov
  • 5,006
  • 17
  • 69
  • 106
3

Every overload for operator new() (and operator delete()) is implicitly and automatically declared static. This is a special rule in C++.

Therefore, you should design your class such that the constructor can also remember how it was allocated, if you need to retain that information:

Foo * p = new (true) Foo(true);

That is, your class would look like this:

class Foo
{
    bool mAllocatedWithMemPool;
public:
    static void * operator new(std::size_t n, bool usePool);
    static void operator delete(bool) throw();
    explicit Foo(bool usePool);
    /* ... */
};

Note that you should always declare the matching delete operator, even though its use is very limited.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084