你能保证析构函数为了当对象被堆栈上声明?(Can you guarantee destructor

2019-07-31 15:56发布

我具有控制基于范围互斥锁定/解锁代码:

void PerformLogin()
{
    ScopeLock < Lock > LoginLock( &m_LoginLock );

    doLoginCommand();

    ScopeLock < SharedMemoryBase > MemoryLock( &m_SharedMemory );

    doStoreLogin();

    ...
}

我可以保证, MemoryLock将之前遭到破坏LoginLock

Answer 1:

是的。 在任何特定的范围本地对象被销毁以相反的顺序,它们被构建。



Answer 2:

是的,析构函数被称为建筑的顺序相反。



Answer 3:

添加到尼尔的答案。

考虑一下,如果对面是真实的,那就是你无法预测析构函数栈声明的变量的顺序。 这将使几乎不可能在堆栈上使用相关的值类型。 考虑

void Foo() {
  Type1 t1;
  Type2 t2(&t1);
  ...
}

如果C ++不保证析构函数排序,像这样直接的代码将是令人难以置信的不安全的,因为这将有可能为前T2的析构函数跑到被破坏T1。 因此,你不能保证T2的析构函数跑了一个有效的T1值。



Answer 4:

这个问题已经回答了,但我想补充一点,我通常都写这样的习惯:

void PerformLogin()
{
    ScopeLock < Lock > LoginLock( &m_LoginLock );
    doLoginCommand();

    {
        ScopeLock < SharedMemoryBase > MemoryLock( &m_SharedMemory );
        doStoreLogin();
        ...
    }
}

在我看来,这使得意图更清晰(*)。 如果你的代码确实是依靠特定的顺序,可能是相关的。 我觉得这使得它不太可能是有人不小心会改变顺序,并导致难以发现错误。 (嗯,这当然是不成问题的,因为我们都已经制定的测试,不是吗?)

我总是写冗余括号中像(a && b) || c (a && b) || c过了,我觉得这件事情很相似。

(*):当然,你可以使用一个评论为好。



Answer 5:

是的,析构函数构造函数相反。 由于析构函数是用来删除其不再需要和构造的对象是使用来创建对象。



文章来源: Can you guarantee destructor order when objects are declared on a stack?