Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is is safe to `delete this` in a virtual member function?

I know already that some forms of "suicide" are safe (to be considered legal), but, is it specifically safe to perform delete this in a virtual member function?

Note, by "safe", I mean whether the "code" generated by the compiler is able to deal with the construct.

Note, I'm not interested in the pros and cons of doing it, just whether I can consider is safe.

Side question: Does the language standard explicitly or implicitly demand that implementations support any forms of the delete this idiom?

I do not consider this a duplicate of Is delete this allowed?. My question is about whether it is safe to do in a virtual member function.

Here is an outline of what I am pursuing to do

class FooBase {
protected:
    virtual void on_idle() { /* no-op by default */ }
};

class Foo : public FooBase {
    void on_idle() override final
    {
        delete this;
    }
};

Note that while Foo needs to be heap allocated, other subclasses possibly do not.

like image 770
Kristian Spangsege Avatar asked Jan 03 '18 21:01

Kristian Spangsege


People also ask

Can you call delete this inside a member function?

Answer: Yes, we can delete “this” pointer inside a member function only if the function call is made by the class object that has been created dynamically i.e. using “new” keyword. As, delete can only be applied on the object that has been created by using “new” keyword only.

Is it safe to delete this C++?

Yes. It should be perfectly fine. "This" is just a pointer. Any pointer will do for delete.

What means delete this C++?

Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression. Delete can be used by either using Delete operator or Delete [ ] operator. New operator is used for dynamic memory allocation which puts variables on heap memory.

Do virtual member functions run faster?

Virtual functions are by definition slower than their non-virtual counterparts; we wanted to measure the performance gains from inlining; using virtual functions would make the difference even more pronounced. In this particular example, CLANG 10 compiler inlined the functions and unrolled the test loop two times.


1 Answers

Yes, so long as you don't use this afterwards, and neither does anyone else with a pointer to *this, and this was guaranteed to be allocated by new as exactly the type you are deleting it as, or possessing a virtual destructor. (ie, never as a member of another object, in a std::vector, as an automatic storage variable, as a static variable, as a temporary, not new[], not placement new, etc etc etc)

This includes calling non-virtual methods, virtual methods, member access, calling dtors, and a myriad of other things; almost anything other than return; on the next line and somehow every other pointer to *this being cleaned up before you delete this; (or deterministically never being used).

As a general rule, the level of control you have to have over your objects lifetime is so great to make delete this; safe that you can refactor the lifetime management to be external to the class and in a smart resource owner, which maybe maintains its state as a pImpl which it deletes. c++ adores value types, and a type that delete this; can never be treated as a value.

There is nothing in the standard that makes delete this; extra dangerous for virtual objects, other than the higher tendency to inherit.

All types that delete this; should have either a virtual destructor or be final to avoid inheritance issues.

like image 92
Yakk - Adam Nevraumont Avatar answered Oct 24 '22 18:10

Yakk - Adam Nevraumont