Является ли new (this) ThisClass () плохой идеей?

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

Я никогда не видел эту идиому, и кажется, что она может быть очень тонкой и грязной, но я не могу думать о проблеме с ней (пока FooViewона окончательна). Это плохая идея?

luqui
источник
related / dupe: stackoverflow.com/questions/58274963/… . Можем ли мы получить полный контекст типа? Это имеет значение.
Натан Оливер

Ответы:

12

Вы можете сделать это, но вам потребуется отмывание памяти для этого, если у вас есть ссылочные или константные члены, или если тип класса изменяется.

Учти это:

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?
}

Чтобы избежать этого неопределенного поведения, вы должны отмыть память, используя std::launder. Компилятор будет предполагать, что время жизни fvне будет зависеть ни от чего, кроме }. Отмывание заставит компилятор предположить, что есть объект, не связанный с fv:

int main() {
    FooView fv{9};

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

Теперь это хорошая идея? Я бы посоветовал против этого, так как это может привести к путанице, но это можно сделать безопасно.

Гийом Расико
источник