risingDarkness
risingDarkness

Reputation: 708

Is it Legal for an Object to Replace itself?

I have a feeling that this is not really legal or involves undefined behaviour, where the member object replaces itself with another instance. I searched here on StackOverflow and Google for quite a while and found mainly people who wanted to delete this;. I am not entirely sure if the delete this; questions are of the same situation, because I did not new my instance and I don't delete it.

Am I right?

Is there an easy way around this if I still need the code to do something like this?

struct Test;

struct Member {
    void fail();
    Test* test;
};

struct Test {
    Test(): member() {
        member.test = this;
    }

    void doStuff() {
        member.fail();
    }

    Member member;
};

void Member::fail() {
    test->member = Member(); // delete the object the current code is executing on
}

int main() {
    Test bla;
    bla.doStuff();
}

Upvotes: 2

Views: 125

Answers (2)

Alecto
Alecto

Reputation: 10740

It's perfectly legal as far as I know, although there's a simpler way to do it. If you've had problems with the above code, it's because the fail method resets the value of the "test" pointer to 0, and it becomes a null pointer. The below code performs the reset without those problems:

struct Member
{
    int value = 0;
    void step() 
    { 
        value++; 
        std::cout << "Member::step()" << std::endl; 
    }
    void fail() 
    { 
        *this = Member(); 
        std::cout << "Member::fail()" <<std::endl; 
    }
    void print() 
    { 
        std::cout << "X::print(): " << value << std::endl; 
    }
};
int main()
{
    Member x;
    x.print();
    x.step();
    x.print();
    x.fail();
    x.print(); 
}

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385204

// delete the object the current code is executing on

Nah, it doesn't delete anything.

All you're doing is constructing a temporary Member object, then invoking *this's copy assignment operator with that temporary as an argument.

From C++'s point of view, this is not a "replacement" of an object, nor does it "delete" the object. It's just a member function call. In this case, the only observable result is that test will be nulled after the call to fail().

Assigning to an object has no effect on its lifetime.

Now, if you started playing around with delete and new, you'd have a problem.

Upvotes: 4

Related Questions