2

I have overloaded new operator in the Base class. However, when I add additional overloaded new to the Derived class gcc compiler does not find new operator in the Base class. Why?

Best, Alex

#include <stdlib.h>
template <class t> class Base {
  public:
    Base() {}
    void * operator new (size_t size, void *loc) { return loc; }
};

template <class t> class Derived : public Base<t> {
  public:
    Derived() {}
    void * operator new (size_t size, int sz, void *loc) { return loc; }

};

void foo() {
  void *loc = malloc(sizeof(Derived<char>));
  Derived<char> *d = new (loc) Derived<char>();
}

gcc output:

   new.cpp: In function ‘void foo()’:
new.cpp:17:45: error: no matching function for call to ‘Derived<char>::operator new(sizetype, void*&)’
  Derived<char> *d = new (loc) Derived<char>();
                                             ^
new.cpp:17:45: note: candidate is:
new.cpp:11:10: note: static void* Derived<t>::operator new(size_t, int, void*) [with t = char; size_t = unsigned int]
   void * operator new (size_t size, int sz, void *loc) { return loc; }
          ^
new.cpp:11:10: note:   candidate expects 3 arguments, 2 provided
Alexander
  • 713
  • 1
  • 7
  • 20
  • You have added (by mistake ?) an extra parameter to the overload in the derived class, so the `new` operator is waiting for an extra parameter. – Holt Nov 17 '15 at 15:33
  • No, I want B::new(size_t, void*) to be called in this example. – Alexander Nov 17 '15 at 15:50

1 Answers1

6

When you invoke the operator new via the placement new expression

new (loc) Derived<char>();

the compiler looks for an overload of operator new in the Derived class (and not the Base class). It finds it, but your overload

void * operator new (size_t size, int sz, void *loc) { return loc; }
//                                ^ additional parameter

accepts more parameters, hence the error.

If you ask why the compiler is not smart enough to invoke the Base's overload of operator new, it is because of name hiding: the operator new overload in the Derived class hides the one of the Base class. If you want to make the Base::operator new overload visible in your Derived class, use

using Base<t>::operator new;
Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Why the compiler does not search for public methods (including operator new) in the Base class in this case? – Alexander Nov 17 '15 at 15:42
  • @Alexander Because of name hiding. The `operator new` overload in the `Derived` class hides the one of the base class. Added this in the answer. – vsoftco Nov 17 '15 at 15:44
  • is not the same as with standard methods? Can multiple operators new (with different parameter sets) coexist in the class tree, can't they? – Alexander Nov 17 '15 at 15:54
  • @Alexander Yes they can. But the `Base` one is hidden. So if you need to use the base overload, i.e. make it visible in the `Derived` class, use `using Base::operator new`. – vsoftco Nov 17 '15 at 15:57