tags:

views:

113

answers:

3

Hi, 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)

PS: Placement delete related code is not shown here.

+3  A: 

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. Sensitivity to the presence of placement new would be a symptom of that.

Potatoswatter
Actually it is a good idea to implement placement and nothrow `new` whenever you implement custom `new` for this very reason. You could break existing code by failing to provide the six versions of new and delete (don't forget array forms).
Alexandre C.
placement `new` isn't often used in code, but STL containers frequently use it to separate their memory allocation from their object construction.
Philip Potter
@Philip: That's a red flag then, since `std::allocator` obtains its memory from `::operator new`. In that case, the solution is to implement a custom allocator, not to enable the standard one.
Potatoswatter
@Potato: no, that's not the problem. The problem is that if `std::vector<MyClass>` needs a placement `new` to construct a `MyClass`, then `MyClass` had better provide one. It doesn't matter where the `vector` got its memory from.
Philip Potter
@Philip: If `vector` is getting its memory from the wrong place, that's a bug. Implementing a custom allocator will also likely require placement new (to the letter of the law, anyway), so it will likely go back in one way or another. Maybe I shouldn't jump to conclusions, but it's definitely an issue.
Potatoswatter
@Potato: you haven't demonstrated what is wrong about the place `vector` gets its memory from.
Philip Potter
A: 

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.

Leonid
A: 

implementations of std::_Construct use the global placement new. So concerns about STL compatability should not be concerns. But the concern about breaking existing code, that may have been written

new ((void*)p) thing;

rather than

::new ((void*)p) thing;

is certainly a valid point.

nbourbaki