Est-ce que new (this) ThisClass () est une mauvaise idée?

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

Je n'ai jamais vu cet idiome, et il semble que cela pourrait être vraiment subtil et désordonné, mais je ne peux pas vraiment penser à un problème avec lui (tant que FooView est définitif). Est-ce une mauvaise idée?

luqui
la source
liés / dupe: stackoverflow.com/questions/58274963/… . Pouvons-nous obtenir le contexte complet du type? C'est important.
NathanOliver

Réponses:

12

Vous pouvez le faire, mais vous aurez besoin de blanchiment de mémoire pour cela si vous avez des membres de référence ou const, ou si le type de la classe change.

Considère ceci:

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

Pour éviter ce comportement indéfini, vous devez blanchir la mémoire à l'aide de std::launder. Le compilateur supposera que la durée de vie de fvne sera affectée par rien sauf }. Le blanchiment obligera le compilateur à supposer qu'il existe un objet, sans rapport avec fv:

int main() {
    FooView fv{9};

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

Est-ce maintenant une bonne idée? Je le déconseille car cela peut prêter à confusion, mais cela peut être fait en toute sécurité.

Guillaume Racicot
la source