2

I read here that

As long as you’re careful, it’s okay (not evil) for an object to commit suicide (delete this).

Here’s how I define “careful”:

You must be absolutely 100% positively sure that this object was allocated via new (not by new[], nor by placement new, nor a local object on the stack, nor a namespace-scope / global, nor a member of another object; but by plain ordinary new).

If I use placement new, what alternatives do I have?

otisonoza
  • 1,334
  • 2
  • 14
  • 32
  • 6
    Not sure what you mean. If you use placement new, you can't call `delete this` . As a matter of fact, reasons for calling `delete this`, although exist, are rare. Are you sure you have one? Aren't we seeing an XY problem? – SergeyA Apr 04 '16 at 13:56
  • 1
    http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – RhinoDevel Apr 04 '16 at 14:00
  • 2
    @SergeyA: Reference required. I believe there's actually a standard defect in this area, because the current wording appear to allow it. "the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object". Placement new does create an object, although it doesn't allocate. See related http://stackoverflow.com/q/4418220/103167 – Ben Voigt Apr 04 '16 at 14:19
  • @BenVoigt, wow! Good catch. Placement new is indeed a new expression, so literally reading the standard allows it. Looks like a defect to me, we all know what's gonna happen in real life :) – SergeyA Apr 04 '16 at 14:25

3 Answers3

3

Placement new is used to separate memory allocation and object lifetime, so you would usually call the destructor explicitly:

myobj->~myclass();

and free the memory later, or continue to use the memory for other purposes.

alain
  • 11,939
  • 2
  • 31
  • 51
0

Placement new means the object is not allocated on the heap, but memory for its storage is provided by the user. Delete in this case would try to deallocate a non-heap block, which is usually fatal...

There's nothing to delete, so you have to do an explicit destructor call:

struct SomeClass {
    SomeClass() { std::cout << "Constuctor\n"; }
    ~SomeClass() { std::cout << "Destructor\n"; }
};

std::aligned_storage<sizeof(SomeClass), alignof(SomeClass)>::type storage;
new(&storage) SomeClass();
reinterpret_cast< SomeClass* >(&storage) -> ~SomeClass();

Having a this pointer only is not enough to do proper destruction in a general case.

Gyorgy Szekely
  • 2,654
  • 3
  • 23
  • 32
0

Since the arrival of std::shared_ptr and std::unique_ptr it has become un-necessary (and undesirable) to write objects that manage their own lifetimes.

Good c++ form requires that one object has one responsibility. Your object's responsibility is the work it performs. The responsibility of a smart pointer is to manage its lifetime.

There is one remaining scenario where you would need to delete this - when writing an object for an old API that demands intrusive reference counting.

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142