It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center
                            
                        
                    
                
                                7年前关闭。
            
                    
此dtor / ctor命令是否正常?如果是,为什么?

在下面的简单功能

TemporaryObject SimpleFunction();
{
    TemporaryObject obj = MakeObj();

    // ...

    return obj;   // Stepping through at this point we hit TemporaryObject::dtor, MyObject::ctor
}

// At call site
MyObject obj = SimpleFunction();


在return语句中,我希望先调用MyObject ctor,然后再调用TemporaryObject dtor。 (可能会先复制TemporaryObject,但此处通常是RVO)。

在VS2010(调试版本)中发生的情况是,首先调用TemporaryObject dtor,然后使用已销毁的对象调用MyObject构造函数。查看内存地址可确认它是传入的销毁对象,如果有任何疑问,则销毁者的副作用是显而易见的。

(为完整起见,MyObject ctor在TemporaryObject中设置一个标志以标记已被复制。TemporaryObjectdtor断言此标志已设置,这是我在这种情况下意识到在“复制”之前发生销毁的方式)。

最佳答案

最少的完整示例,带有答案

是的,dtor在复制构造函数之前被调用,但不是出于您似乎认为的原因。

关键的观察是MyObject::dtor被调用了两次(以防两个不同的对象,以防我们仍然倾向于得出疯狂的编译器错误结论)。因此,我们猜测有一个副本正在幕后发生,而且可以肯定的是,尽管您可能听说过,即使您提供了一个不同的构造函数,编译器仍会生成一个副本构造函数。

因此,如果取消注释下面的副本构造函数,您将获得一些输出,可以更好地描述正在发生的事情,并且可以正确处理mActive标志

struct TemporaryObject
{
    TemporaryObject()
        :
    mActive(true)
    {
        std::cout << "TemporaryObject::ctor mActive = " << mActive << ", this = " << (void*)this << std::endl;
    }

   /* TemporaryObject(const TemporaryObject& obj)
        :
    mActive(obj.mActive)
    {
        obj.mActive = false;
        std::cout << "TemporaryObject::copy_ctor mActive = " << mActive << ", this = " << (void*)this << std::endl;
    }*/

    ~TemporaryObject()
    {
        std::cout << "TemporaryObject::dtor mActive = " << mActive << ", this = " << (void*)this << std::endl;
        // assert(!mActive);
    }

    mutable bool mActive;
};

struct MyObject
{
    MyObject(const TemporaryObject& obj)
    {
        std::cout << "MyObject::ctor obj.mActive = " << obj.mActive << ", &obj = " << (void*)(&obj) << std::endl;
        obj.mActive = false;
    }
};

TemporaryObject SimpleFunction()
{
    TemporaryObject obj;

    // Do stuff

    return obj;
}

int main()
{
    MyObject obj = SimpleFunction();
}


输出:

TemporaryObject::ctor mActive = 1, this = 00EFF4AB
TemporaryObject::dtor mActive = 1, this = 00EFF4AB
MyObject::ctor obj.mActive = 1, &obj = 00EFF4D7
TemporaryObject::dtor mActive = 0, this = 00EFF4D7

07-26 08:30