Czy nowy (this) ThisClass () to zły pomysł?

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

Nigdy nie widziałem tego idiomu i wydaje się, że może być bardzo subtelny i nieuporządkowany, ale tak naprawdę nie mogę wymyślić z nim problemu (dopóki FooViewjest ostateczny). Czy to zły pomysł?

luqui
źródło
Powiązane / dupe: stackoverflow.com/questions/58274963/... . Czy możemy uzyskać pełny kontekst tego typu? To ma znaczenie.
NathanOliver

Odpowiedzi:

12

Możesz to zrobić, ale będziesz potrzebował do tego prania pamięci, jeśli masz odwołania lub stałe elementy, lub jeśli typ klasy się zmieni.

Rozważ to:

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

Aby uniknąć tego niezdefiniowanego zachowania, należy prać pamięć za pomocą std::launder. Kompilator przyjmie, że na życie fvnie wpłynie nic oprócz }. Pranie powoduje, że kompilator przyjmuje, że istnieje obiekt niezwiązany z fv:

int main() {
    FooView fv{9};

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

Czy to dobry pomysł? Odradzałbym to, ponieważ może to prowadzić do zamieszania, ale można to zrobić bezpiecznie.

Racilla Guillaume
źródło