如果我只在其对象上调用一个方法,shared_ptr 会被具体化吗?
Would a shared_ptr be materialized if I'm only calling a method on its object?
我有一个关于 c++ shared_ptr
s 的小问题。请考虑以下伪代码,
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()
仅影响 when 临时实体化,而不影响 whether.
在实践中,关于何时临时对象被具体化的规则实际上只是关于谁必须为临时对象分配内存的规则临时对象的 构造 发生在 GetFoo
甚至 returns 之前,就像 C++17 之前一样。这是因为只有 GetFoo
或其调用者之一真正知道如何执行构造( 例如 将哪些参数传递给 shared_ptr
构造函数)。
综上所述,只有当编译器能够证明它不会改变程序的可观察行为时,才可以省略具体化。由于 shared_ptr
相当复杂(如您所知,它有一个带有原子计数器的控制块),编译器不太可能证明这一点。事实上,即使创建 shared_ptr
的函数的定义驻留在同一个翻译单元中,appears shared_ptr
对象的初始化和销毁也只是内联,而不是省略。
我有一个关于 c++ shared_ptr
s 的小问题。请考虑以下伪代码,
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()
仅影响 when 临时实体化,而不影响 whether.
在实践中,关于何时临时对象被具体化的规则实际上只是关于谁必须为临时对象分配内存的规则临时对象的 构造 发生在 GetFoo
甚至 returns 之前,就像 C++17 之前一样。这是因为只有 GetFoo
或其调用者之一真正知道如何执行构造( 例如 将哪些参数传递给 shared_ptr
构造函数)。
综上所述,只有当编译器能够证明它不会改变程序的可观察行为时,才可以省略具体化。由于 shared_ptr
相当复杂(如您所知,它有一个带有原子计数器的控制块),编译器不太可能证明这一点。事实上,即使创建 shared_ptr
的函数的定义驻留在同一个翻译单元中,appears shared_ptr
对象的初始化和销毁也只是内联,而不是省略。