Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it necessary to overload placement new operator, when we overload new operator?

Tags:

c++

I have below piece of code

class Test 
{
public:
    Test(){}
    Test(int i) {}

  void* operator new (size_t size)
  {
      void *p = malloc(size);
      return p;
  }
  //void* operator new (size_t size, Test *p)
  //{
     // return p;
  //}
};

int main() { 
   Test *p = new Test;
   int i = 10;
   new(p) Test(i);
}

Above piece of code does not compile in visual studio, unless i uncomment out the overloaded placement new operator function. If i comment out normal overloaded new, in that case also it works fine. Is overloading of placement new mandatory when overloading normal new operator(If placement new need to be used for that class)

Placement delete related code is not shown here.

like image 923
bjskishore123 Avatar asked Aug 30 '10 11:08

bjskishore123


People also ask

Is it possible to overload the new operators?

New and Delete operators can be overloaded globally or they can be overloaded for specific classes.

What is mandatory for operator overloading?

1) For operator overloading to work, at least one of the operands must be a user-defined class object. 2) Assignment Operator: Compiler automatically creates a default assignment operator with every class.

What should the first parameter for an overloaded new operator?

The first parameter is always an ostream object (we've mostly used cout, so far). Because of this, it cannot be defined as a member function (it would have to be a member of the ostream class, which we cannot change). The << and >> operators should always be defined as outside functions (usually friend functions).

Is the correct syntax to overload the new operator?

The general form of overloading the new operator is as follows: return_type * operator new(size_t size) { // Memory allocation // ... } return_type is a type (class) to which the operator function returns a pointer for which memory is allocated by a special (non-standard method);


2 Answers

Usually no, since it's not often used. But it might be necessary, since when you overload operator new in a class, it hides all overloads of the global ::operator new.

So, if you want to use placement new on objects of that class, do; otherwise don't. Same goes for nothrow new.

If you've just changed the allocation scheme, and you're surprised that someone somewhere is using placement new behind your back, that might be something to investigate before applying this band-aid.

If the class is used inside standard library containers, not directly with new, the custom allocation scheme should be defined by an Allocator class, not an overload. The default allocator std::allocator does not respect member operator new overloads, but bypasses them. See below.


Disclaimer: class-scope operator new overloads are mainly useful for debugging, and even then it's tricky to get reliably meaningful semantics. Beware:

  • You need to also overload operator delete. (Not done in the example in this question.)

  • Overloads will be bypassed by the qualified syntax ::new T. You cannot prevent such bypassing. This is the way that std::allocator<T> allocates things. You can specialize std::allocator for your types, but that's some way into the rabbit-hole already.

  • For each ::operator new overload introduced by any library, including the canonical placement new from <new>, you will have to consider whether it applies to your class and decide whether to add an overload, or otherwise contend with the failure of unqualified new expressions.

  • For each ::operator new you adopt into your class, you must supply the corresponding member placement operator delete with correct semantics. This is called in case the constructor exits by exception. Failing to have it would result in a memory leak only under very specific circumstances, in a possibly resource-constrained pool.

In summary, member operator new is the antithesis of defensive coding.

like image 115
Potatoswatter Avatar answered Oct 19 '22 23:10

Potatoswatter


Placement new operator doesn't exist by default for a class so when you're making a call to new(p) Test(i); C++ compiler can't find a definition of the commented function in the above example. If you uncomment the placement operator new for your class, and comment out the "normal" one then the default "normal" new operator will be used and your code will compile.

like image 24
Leonid Avatar answered Oct 20 '22 00:10

Leonid