给出 shared_ptr<void>
的最有效方法是什么?到一个对象,该对象在存储到其最终目的地之前将其传递给另一个私有(private)方法?
这很难描述......也许用代码提问会更好地说明问题:
class Example{
public:
void give(std::shared_ptr<void> data) { // [A] which signature is best here?
void give(std::shared_ptr<void> & data) { // [B]
// the caller keeps it's shared_ptr
m_give(data); // [A] which of these is preferable?
m_give(std::move(data)); // [B]
}
private:
void m_give(std::shared_ptr<void> data) { // [A] which signature is best here
void m_give(std::shared_ptr<void> & data) { // [B]
void m_give(std::shared_ptr<void> && data) { // [C]
// only `give()` will ever call this
m_data = data; // [A] which of these is preferable?
m_data = std::move(data); // [B]
}
// members
std::shared_ptr<void> m_data;
};
你会如何建立这样的机制?
最佳答案
需要一个客观的标准来定义“最有效的方法”。
您澄清说您只考虑一个引用计数增量。我建议一个稍微不直观的解决方案,它正是这样做的:
#include <memory>
class obj {};
class Example {
public:
void give(std::shared_ptr<obj> data)
{
m_give(data);
}
private:
void m_give(std::shared_ptr<obj> & data)
{
m_data=std::move(data);
}
std::shared_ptr<obj> m_data;
};
int main()
{
auto ptr=std::make_shared<obj>();
Example e;
e.give(ptr);
return 0;
}
如果您使用调试器逐步运行此操作,您应该会看到 e.give(ptr);
仅增加引用计数一次,以复制构造 give()
的参数。 shared_ptr
被移动到它的最终安息位置,没有任何进一步的引用计数。结束。
这不是实现这一目标的唯一方法,但这种方法的好处是让您可以选择进一步优化。如果调用者希望放弃 shared_ptr
的所有权,而不发生任何引用计数:
e.give(std::move(ptr));
调用者实际上放弃了它的引用。现在,在调试器中单步执行这一奥德赛将显示发生了两个移动,一个移动构造 give()
的参数,以及相同的第二个移动。引用计数没有变化。
通过一些进一步的工作,也许可以鱼与熊掌兼得:要么使用单个引用计数增量来保留调用者的所有权,要么使用单个移动操作来保留调用者的所有权。但最终的使用语法可能有点不方便。如果主要目标是针对调用者保留其所有权的情况进行优化,正如您所暗示的,这种方法的结果几乎是理所当然的,但您仍然保留根据具体情况决定每个调用者是否可以放弃它的所有权,如果是的话,可以从这 block 岩石中榨取更多的汁液。
关于c++ - 通过2层方法传递shared_ptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73029309/