Re: Why no placement delete?
Andy Venikov wrote:
Hyman Rosen wrote:
Andy Venikov wrote:
(you can)
X * px = new (regionAllocator) X;
But you can't
delete (regionAllocator) px;
you can only
delete px;
Just do
px->~X();
regionAllocator.free(px);
Yes, this is what I'm forced to do. But it looks ugly that for a single
new you actually need two calls. In my case I just created a templated
"Destruct" function that does both.
I agree it's ugly, but so is the placement-new syntax IMHO (the explicit
dtor call is just even more ugly).
If I were faced with such (which I have never been yet) I would prefer
to use some more machinery to hide all that new and placement stuff
between some interface.
Personally I think new-with-parameter is just something that's better
and more clearly done with a named function (except for the void* case,
as we already have that operator-new).
I have done a simple scratch program below.
br,
Martin
[CODE]
#include "stdafx.h"
#include <boost/smart_ptr.hpp>
#include "unique_ptr.hpp" // from
http://home.roadrunner.com/~hinnant/unique_ptr03.html
#include <string>
#include <iostream>
using namespace std;
using namespace boost;
struct X {
string m_;
X() {
// throw runtime_error("Check that ctor exceptions are handled
correctly.");
}
};
struct destruct_X {
void operator()(X* obj) {
if(obj) {
obj->~X();
free(obj);
}
}
};
//! create a new X object in a custom memory pool
//! The knowledge of how to delete the object is already encapsulated
//! in the shared_ptr instance.
shared_ptr<X> construct_shared_x() {
void* p = malloc(sizeof(X));
if(!p)
throw bad_alloc("struct X");
try {
return shared_ptr<X>( new (p) X, destruct_X() );
} catch(...) {
free(p);
throw;
}
}
//! create a new X object in a custom memory pool
//! The Unique pointer takes care of deallocating it correctly, but
//! if you absolutely want to, you can call release() on the
//! returned uptr to manually manage the raw ptr.
typedef unique_ptr<X, destruct_X> PooledXPtr;
PooledXPtr construct_unique_x() {
void* p = malloc(sizeof(X));
if(!p)
throw bad_alloc("struct X");
try {
return PooledXPtr( new (p) X );
} catch(...) {
free(p);
throw;
}
}
int main(int argc, char* argv[])
{
// Dump leaked memory (Windows specific)
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
try {
shared_ptr<X> px = construct_shared_x();
px->m_ = "Shared!";
cout << px->m_ << "\n";
} catch(...) {
cout << "Failed shared.\n";
}
try {
PooledXPtr ux = construct_unique_x();
ux->m_ = "Unique!";
cout << ux->m_ << "\n";
} catch(...) {
cout << "Failed unique.\n";
}
try {
X* x = construct_unique_x().release();
x->m_ = "Raw!";
cout << x->m_ << "\n";
destruct_X()(x);
} catch(...) {
cout << "Failed raw.\n";
}
return 0;
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]