9

For example, we have a function like that:

template <typename TYPE>
void construct_and_destruct(TYPE & object)
{
    //...
}

We cant call constructor and destructor like object.Type() and object.~Type() (no true now) ( Whyy? =C )

To call the constructor we can like new(&object) TYPE(). And I dont know how to call destructor (no exist placement delete). How to do this?

4Bytes
  • 325
  • 3
  • 8
  • You should split the code you're interested from the dtor and into a separate member function and call that instead. – Nikos C. Nov 03 '12 at 18:33

4 Answers4

8

You can call the destructor as:

object.~TYPE();

but it's likely not what you want, and are subject to a double delete.

The constructor is as simple as:

object = TYPE();
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • You're right, but `object = TYPE();` perform additional `operator =`. Instead this better use placement new (with strange syntax **=)**). – 4Bytes Nov 03 '12 at 16:20
  • @4Bytes: No. Just don't do `object.~TYPE(); new (object) TYPE();` It's much cleaner to use `object = TYPE();` Let the system clean up after itself. – David Hammen Nov 03 '12 at 17:24
  • @David This is incorrect: You are doing an assignment. `TYPE` must assume in its assignment operator that one of its constructors previously has been called. You will be violating that. – Johannes Schaub - litb Nov 03 '12 at 21:51
  • @JohannesSchaub-litb - I'm assuming that 4Bytes wants to "reset" an object originally declared as `TYPE object` to some primeval state, and is doing so via `new (&object) TYPE();`. There's a problem with just using placement new here: That placement new can cause resources allocated in `object` to leak. Solution: Destruct `object` before reconstructing it. This is why I think h4Bytes is asking about explicitly calling the destructor. There's a much better way to accomplish what he wants besides this convoluted call to the destructor followed by placement new. – David Hammen Nov 03 '12 at 22:42
  • @JohannesSchaub-litb - I made an error in my comment from five hours ago when I wrote `new (object) TYPE()`. That's illegal of course; the argument to placement new is supposed to be a pointer. What I meant was `new (&object) TYPE()` -- or perhaps something other than the default constructor. – David Hammen Nov 03 '12 at 22:53
  • have to agree with Luchian.. if you're passing in a TYPE &object, then its almost certainly already been constructed by the caller, so don't use a placement new on it... If the function took raw memory as an argument, then its more likely to need a placement new on it. – James Podesta Mar 09 '17 at 12:44
3

I came at this with a slightly different problem, but also for placement-new/delete, and the solution should be similar.

Given a dependent type name the placement new:

new (&foo) typename AT::T(arg, arg, arg);

The associated delete is tricky:

foo.~ typename AT::T();  // Doesn't work, nor do variations of syntax

The modern solution seems to be std::destroy_at(&foo) but my compiler doesnt have full C++17. Rolling a basic version of your own isn't difficult however:

template <typename T>
constexpr void destroy_at(T* p)
{
  p->~T();
}

Seems fine.

FDS
  • 4,999
  • 2
  • 22
  • 13
1

object.~TYPE() and object.~TYPE::TYPE() are both correct I think. Sounds a bit dubious however, what are you trying to achieve?

john
  • 85,011
  • 4
  • 57
  • 81
  • Nope, `object.~TYPE()` is incorrect. I know that construct_and_destruct is useless function, but I write this for **example**. – 4Bytes Nov 03 '12 at 16:10
  • 2
    `object.~TYPE()` is correct. That said, why would you want to call the destructor? – David Hammen Nov 03 '12 at 16:13
  • @David Hammen, sorry, I was wrong. Destructor work as well. It's required to perform my tasks. – 4Bytes Nov 03 '12 at 16:35
  • @DavidHammen If you had a union type, with some variable for descriminating which type it is, you would need to call the right destructor in your own destructor. – Jeffrey Drake May 06 '14 at 04:49
  • @DavidHammen: Also, if you allocated with a custom `new` operator, you cannot call the standard `delete` but you need to call your own. – Hector Nov 12 '14 at 19:02
1

Try this Calling destructor with decltype and\or std::remove_reference, it worked for me to call the destructor of an unqualified type (unspecified inner class inside a template argument)...