Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is new (this) ThisClass() a bad idea?

class FooView final : public Something
{
    ...
    void refresh()
    {
        this->~FooView();
        new (this) FooView();
    }
}

I have never seen this idiom, and it seems like it could be really subtle and messy, but I can't actually think of a problem with it (as long as FooView is final). Is this a bad idea?

like image 361
luqui Avatar asked Jan 10 '20 21:01

luqui


1 Answers

You can do that, but you'll need memory laundering for that if you have reference or const members, or if the type of the class changes.

Consider this:

struct FooView {
    const int val;

    void refresh()
    {
        this->~FooView();
        new (this) FooView{5};
    }
}

int main() {
    FooView fv{9};

    std::cout << fv.val; // surely 9!
    fv.refresh();
    std::cout << fv.val; // hmm... val is a const object, so it's 9 still?
}

To avoid this undefined behaviour, you should launder the memory using std::launder. The compiler will assume that the lifetime of fv won't be affected by anything except }. Laundering will make the compiler assume there is an object, unrelated to fv:

int main() {
    FooView fv{9};

    std::cout << fv.val; // surely 9!
    fv.refresh();
    std::cout << std::launder(&fv)->val; // yay, 5
}

Now is it a good idea? I'd advise against it since it can lead to confusion but it can be done safely.

like image 166
Guillaume Racicot Avatar answered Sep 24 '22 06:09

Guillaume Racicot