Is this object reinitialization via explicit constructor and destructor calls technically correct?

Viewed 54

I put a single local variable through two object life cycles:

class Thing
{
    int i;

public:
    Thing() : i(44) {}
    ~Thing() { i = 0; }
    void set(int i) { this->i = i; }
    void report() const { std::cout << i << std::endl; }
};

...

Thing thing;
thing.report();
thing.set(72);
thing.report();
thing.~Thing();

new (&thing) Thing();
thing.report();
thing.set(97);
thing.report();
thing.~Thing();

thing.report();

I tentatively expect this to print the following:

44
72
44
97
0

And so it does.

But is this code guaranteed to work like that? Or does it invoke undefined behavior or some such? (I'm especially suspicious of the last report() call; I only threw that one in out of curiosity.)

Also what if the thing is a member:

struct Owner
{
    Thing thing;

    void go()
    {
        thing.report();
        thing.~Thing();

        new (&thing) Thing();
        thing.report();
    }
};

...

Owner owner;
owner.go();
Owner().go();

This also seems to work for me. Should it?

(Yeah I know this technique is dangerous in various ways. I'm not trying to ask or say anything about whether anybody should ever use it. I just want to know whether it's really allowed by the standard, rather than merely being allowed by my current compiler setup.)

0 Answers
Related