New (this) ThisClass () é uma má idéia?

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

Eu nunca vi esse idioma e parece que pode ser realmente sutil e confuso, mas não consigo pensar em um problema com ele (desde que FooViewseja final). Isso é uma má ideia?

luqui
fonte
related / dupe: stackoverflow.com/questions/58274963/… . Podemos obter o contexto completo do tipo? Isto é importante.
NathanOliver 10/01

Respostas:

12

Você pode fazer isso, mas precisará de lavagem de memória para isso se tiver membros de referência ou const, ou se o tipo da classe for alterado.

Considere isto:

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

Para evitar esse comportamento indefinido, você deve lavar a memória usando std::launder. O compilador assumirá que o tempo de vida útil fvnão será afetado por nada, exceto }. A lavagem fará o compilador assumir que há um objeto, não relacionado a fv:

int main() {
    FooView fv{9};

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

Agora é uma boa ideia? Eu desaconselho, pois isso pode causar confusão, mas pode ser feito com segurança.

Guillaume Racicot
fonte