Có phải mới (this) ThisClass () là một ý tưởng tồi?


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

Tôi chưa bao giờ thấy thành ngữ này, và có vẻ như nó có thể thực sự tinh tế và lộn xộn, nhưng tôi thực sự không thể nghĩ ra một vấn đề với nó (miễn FooViewlà cuối cùng). Đây có phải là một ý tưởng tồi?


liên quan / dupe: stackoverflow.com/questions/58274963/ . Chúng ta có thể có được bối cảnh đầy đủ của các loại? Nó không thành vấn đề.
NathanOliver

Câu trả lời:


12

Bạn có thể làm điều đó, nhưng bạn sẽ cần rửa bộ nhớ cho điều đó nếu bạn có thành viên tham chiếu hoặc const, hoặc nếu loại lớp thay đổi.

Xem xét điều này:

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

Để tránh hành vi không xác định này, bạn nên rửa bộ nhớ bằng cách sử dụng std::launder. Trình biên dịch sẽ cho rằng thời gian tồn tại fvsẽ không bị ảnh hưởng bởi bất cứ điều gì ngoại trừ }. Rửa sẽ làm cho trình biên dịch giả định có một đối tượng, không liên quan đến fv:

int main() {
    FooView fv{9};

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

Bây giờ nó là một ý tưởng tốt? Tôi khuyên bạn nên chống lại nó vì nó có thể dẫn đến nhầm lẫn nhưng nó có thể được thực hiện một cách an toàn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.