How Could I Sensibly Overload Placement Operator New

How could I sensibly overload placement operator new?

The correct answer is you cannot replace operator placement new.

§18.4.​1.3 Placement forms

These functions are reserved, a C++ program may not define functions that displace the versions in the Standard C++ library.

The rationale: The only purpose of the allocation and deallocation operators is to allocate and deallocate memory, so when given memory nothing more should be done. (The standard specifically notes that these functions "Intentionally perform no other action.")

Placement new With Overloaded Ordinary new Operator

Since you have defined operator new in your class, you need to use the global new to use the placement version of it.

#include <new>

...

::new (reinterpret_cast<MyType*>(ptr)) MyType(*this);

boost::make_shared is not calling (placement) operator new?

Looking as the source of make_shared, it uses the global placement new operator, instead of the new operator supplied by your class.

::new( pv ) T();

Unfortunately (as least on OS X) (according to the standard), you cannot define your own global placement new operator. It appears that allocate_shared is more along the lines of what you're looking for.

Edit:

An alternative could be to actually write a version of make_shared which uses the class's placement new instead of the global one. It's only about 10 lines of code, and should be fine so long as you honor the license of the original code.

Can I use global operator new for a class having operator new overloaded?

The overloaded operator new and operator delete will always be used unless you explicitly do something like this:

// Allocate using global new.
MyClass* my_object = ::new MyClass();

// Use object normally.
my_object->my_method();

// Deallocate using global delete.
::delete my_object;

Or, as a somewhat extreme illustrative example, something like this:

#include <new>

// Use global placement new to allocate in a buffer created by global new.
MyClass* my_object = ::new(::operator new(sizeof(MyClass))) MyClass()

// Use object normally.
my_object->my_method();

// Explicitly invoke destructor.
my_object->~MyClass();

// Explicitly deallocate memory.
::operator delete(my_object);

Hope this helps.

Overloading the new operator

You can overload operator new, but that overloaded operator doesn't return an object. It returns the memory for an object, and the implementation arranges for the constructor to be called.

So you can't do quite what you want.

Instead, if the cost you're trying to avoid is that of memory allocation, then your overload can assign some memory from a pre-allocated block. Obviously you're then responsible for tracking what's free and what isn't, and your challenge is to do this more efficiently than the allocator that comes with the PS2 devkit. That might not be too hard - you have an unfair advantage if you're only dealing with one class, and assuming nobody derives from it, that the size of the allocations is fixed.

If the cost you're trying to avoid is that of calling the constructor, then operator new doesn't help you, but you could write a sort of wrapper:

struct FooWrapper {
Foo *foo;
FooWrapper(): foo(choose_a_pre_existing_foo()) { }
~FooWrapper() {
foo->reset(); // clear up anything that shouldn't be kept
return_to_the_pool_for_reuse(foo);
}
private:
FooWrapper(const FooWrapper &);
FooWrapper &operator=(const FooWrapper &);
};

Foo *choose_a_pre_existing_foo() {
// possibly some kind of synchronization needed if list is global
// and program is multi-threaded.
if list_of_foos.empty() {
return new Foo();
} else {
Foo *f = list_of_foos.back();
list_of_foos.pop_back();
return f;
}
}

Why would you ever make operator `new` private?

Lots of embedded C++ need to guarantee that NO dynamic allocations are done once the system is started. The aeronautics, automotive and medical device industry often have this requirement. See the following links for such coding standards and the rational behind it:

  • http://www.stroustrup.com/JSF-AV-rules.pdf
  • http://www.qa-systems.com/tools/qa-misra/

Can I use placement new(this) in operator=?

As Herb Sutter in "Exceptional C++" states, it is not exception safe. That means, if anything is going wrong during new or construction of the new object, the left hand operand of the assignment is in bad (undefined) state, calling for more trouble. I would strongly recommend using the copy & swap idiom.

Applepie& Applepie::operator=(Applepie copy)
{
swap(m_crust, copy.m_crust);
swap(m_filling, copy.m_filling);
return *this;
}

When your object uses the Pimpl idiom (pointer to implementation) also, the swap is done by changing only two pointers.



Related Topics



Leave a reply



Submit