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
Neatest Way to Loop Over a Range of Integers
Why How to Implicitly Convert an Int Literal to an Int * in C But Not in C++
What's the Difference Between Cout<<Cout and Cout<<&Cout in C++
C++ Get String from Clipboard on Linux
Qt - Qpushbutton Text Formatting
Capturing H264 Stream with Opencv
Error C2228: Left of '.Size' Must Have Class/Struct/Union
How to Read System Information in C++
Test Whether a Class Is Polymorphic
How to Add Playable(Such as Wav,Wmv) Header with Pcm Data/Buffer in iOS
Initialising Reference in Constructor C++
Findwindow Does Not Find the a Window
When to Mark a Function in C++ as a Virtual
Why Compile Error with Enable_If
Opencv 2.4.2 Calcopticalflowpyrlk Doesn't Find Any Points