我有一个关于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()
时,是否会实现shared_ptr<Foo>
(即创建一个atomic_counter等)?或者编译器可以进一步简化最后一条语句吗?
语言规则要求即使立即丢弃shared_ptr<Foo>
也要物化。调用->run()
只影响临时被物化时的,而不影响是否。
GetFoo
返回之前,就像c++ 17之前一样。这是因为只有GetFoo
或它的一个调用者真正知道如何执行构造()。传递给shared_ptr
构造函数的参数)。
尽管如此,只有当编译器能够证明物化不会改变程序的可观察行为时,才可以省略物化。由于shared_ptr
相当复杂(它有一个带有原子计数器的控制块,您似乎已经意识到),编译器不太可能证明这一点。实际上,即使创建shared_ptr
的函数的定义驻留在同一个转换单元中,shared_ptr
对象的初始化和销毁似乎只是内联的,而不是省略的。