在自动变量破坏之前或之后创建的C++返回值?

max*_*olk 19 c++ locking

在C++中是否保证在函数中的自动变量被销毁之前创建的返回值?公告篮::获取:

class Basket
{
public:
  // Gift is a struct containing safely copyable things like int or string
  Gift gift;
  // Used to protect access and changes to gift
  Mutex mutex;

  // Copy gift into present, while locked to be thread safe
  void put (const Gift & gift)
  {
    Lock lock(mutex);   // Constructor locks, destructor unlocks mutex
    this->gift = gift;  // Gift assignment operator
  }

  // Return a memberwise-copy of gift, tries to be thread safe (but is it?)
  Gift get ()
  {
    Lock lock(mutex);  // Constructor locks, destructor unlocks mutex
    return gift;       // Gift copy constructor
  }
};
Run Code Online (Sandbox Code Playgroud)

在销毁锁定对象之前,我需要Basket :: get来执行其Gift copy构造函数(返回的temp对象).否则,返回的礼物对象可能会被同时调用put损坏.

我的测试显示礼品副本确实在锁定销毁之前创建,但是,它是否有保证?如果没有,我需要在函数内部创建第二个临时函数,例如:

  Gift get ()
  {
    Gift result;
    {
      Lock lock(mutex);
      result = gift;
    }
    return result;
  }
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 14

是的,自动变量将保留在范围内,直到返回完成.如果您使用的是优化的编译器,尤其如此return:

Gift get() 
{ 
    Lock lock(mutex);
    return gift;
} 

Gift g = basket.get();
Run Code Online (Sandbox Code Playgroud)

这对于这个序列来说是等价的:

Gift g;
Lock lock(mutex);
g = Gift(gift);
~lock();
Run Code Online (Sandbox Code Playgroud)

可以优化以更像这样:

void get(Gift &ret) 
{ 
    Lock lock(mutex);
    ret = gift;
} 

Gift g;
basket.get(g);
Run Code Online (Sandbox Code Playgroud)

这对于这个序列来说是等价的:

Gift g;
Lock lock(mutex);
g = gift;
~lock();
Run Code Online (Sandbox Code Playgroud)

换句话说,临时可以删除return.


小智 5

这是有保证的。在销毁发生之前复制返回值(如有必要)。这是一个类似的问题/答案,它很好地描述了序列。

C++ 中的作用域和返回值