Is it allowed to call destructor explicitly followed by placement new on a variable with fixed lifetime?

后端 未结 2 2047
醉话见心
醉话见心 2020-12-17 09:33

I know that calling destructor explicitly can lead to undefined behavior because of double destructor calling, like here:

#include 

int main()         


        
2条回答
  •  感情败类
    2020-12-17 10:02

    This is not a good idea, because you can still end up running the destructor twice if the constructor of the new object throws an exception. That is, the destructor will always run at the end of the scope, even if you leave the scope exceptionally.

    Here is a sample program that exhibits this behavior (Ideone link):

    #include 
    #include 
    using namespace std;
     
    struct Foo
    {
        Foo(bool should_throw) {
            if(should_throw)
                throw std::logic_error("Constructor failed");
            cout << "Constructed at " << this << endl;
        }
        ~Foo() {
            cout << "Destroyed at " << this << endl;
        }
    };
     
    void double_free_anyway()
    {
        Foo f(false);
        f.~Foo();
    
        // This constructor will throw, so the object is not considered constructed.
        new (&f) Foo(true);
    
        // The compiler re-destroys the old value at the end of the scope.
    }
     
    int main() {
        try {
            double_free_anyway();
        } catch(std::logic_error& e) {
            cout << "Error: " << e.what();
        }
    }
    

    This prints:

    Constructed at 0x7fff41ebf03f

    Destroyed at 0x7fff41ebf03f

    Destroyed at 0x7fff41ebf03f

    Error: Constructor failed

提交回复
热议问题