首页 > 解决方案 > 如果我只在其对象上调用一个方法,shared_ptr 会被具体化吗?

问题描述

我有一个关于 c++shared_ptr的小问题。请考虑以下伪代码,

class Foo{
  int run();
}

class Bar{
  // NOTE: returns a shared_ptr, not a const ref
  shared_ptr<Foo> GetFoo() const;
}

Bar bar{...};
int k = bar.GetFoo()->run();

在这种情况下,当我们调用时bar.GetFoo(),ashared_ptr<Foo>会被物化(即创建 atomic_counter 等)吗?还是编译器可以进一步简化最后一条语句?

标签: c++stdsmart-pointers

解决方案


语言规则要求 ashared_ptr<Foo>被具体化,即使它被立即丢弃。调用->run()仅影响临时对象何时实现而不影响.

在实践中,关于何时实现临时对象的规则实际上只是关于谁必须为临时对象分配内存的规则。临时对象的构造发生在GetFoo甚至返回之前,就像 C++17 之前的版本一样。这是因为只有GetFoo或其中一个被调用者实际上知道如何执行构造(例如,将哪些参数传递给shared_ptr构造函数)。

话虽如此,只有当编译器可以证明它不会改变程序的可观察行为时,才能省略实现。由于shared_ptr相当复杂(您似乎知道它有一个带有原子计数器的控制块),编译器不太可能证明这一点。事实上,即使创建函数的定义shared_ptr驻留在同一个翻译单元中,对象的初始化和销毁​​似乎shared_ptr只是内联,而不是省略。


推荐阅读