对象替换本身是否合法?

时间:2016-10-24 15:55:41

标签: c++ memory undefined-behavior

我感觉这不是合法的或涉及未定义的行为,其中成员对象用另一个实例替换自己。我在StackOverflow和Google上搜索了很长一段时间,主要找到想要delete this;的人。我不完全确定delete this;问题是否属于同一情况,因为我没有new我的实例而我没有delete

我是对的吗?

如果我还需要代码来做这样的事情,有没有一个简单的方法呢?

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();
}

2 个答案:

答案 0 :(得分:4)

// delete the object the current code is executing on

不,它不会删除任何内容。

您所做的只是构建一个临时Member对象,然后使用该临时值作为参数调用*this的复制赋值运算符。

从C ++的角度来看,这不是对象的“替代”,也不是“删除”对象。它只是一个成员函数调用。在这种情况下,唯一可观察的结果是在调用testfail()将被取消。

分配给对象对其生命周期没有影响。

现在,如果您开始使用deletenew,那么您就会遇到问题。

答案 1 :(得分:0)

据我所知,这是完全合法的,尽管有一种更简单的方法。如果您对上述代码有问题,那么因为失败方法会重置" test"指向0的指针,它变为空指针。以下代码执行重置而没有这些问题:

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(); 
}