c++ - 返回对象时 ctor/dtor 的顺序

标签 c++ visual-studio-2010

<分区>

这个 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();

在返回语句中,我希望调用 MyObject ctor,然后调用 TemporaryObject dtor。 (可能会首先复制 TemporaryObject,但这里的 RVO 很典型)。

在 VS2010(调试构建)中发生的事情是首先调用 TemporaryObject dtor,然后使用被破坏的对象调用 MyObject 构造函数。查看内存地址可以确认传入的是被破坏的对象,如果有任何疑问,析构函数的副作用是显而易见的。

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

最佳答案

最小的完整示例,带答案

是的,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

关于c++ - 返回对象时 ctor/dtor 的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12928133/

相关文章:

c++ - 在C/C++中写一个非打印字符的行为是什么?

c++ - 在 OpenGL 中渲染混合线

c++ - 不能 push_back 到 vector - 没有给出过载错误

c# - 在 DataGridView 中以编程方式选择行

visual-studio-2010 - Visual Studio 数据库项目回滚脚本

C++ "Maze"赋值

c++ - 无法在 C++17 之前的模式下使用 static constexpr 进行编译

unit-testing - 在构建单元测试项目时,VS 2010 找不到要测试的引用程序集

vb.net - WCF : Could not establish trust relationship for the SSL/TLS secure channel with authority error

c++ - 未处理的异常堆栈溢出 win32 控制台应用程序