C++ 将共享指针传递给非所有者函数时的最佳实践是什么?
由于使用共享指针,我经常在希望将它们传递给不(必须)拥有对象的函数的情况下运行。因为我知道对象在函数调用期间是有效的,所以我有四个传递指针的选项:C++ 将共享指针传递给非所有者函数时的最佳实践是什么?,c++,pointers,C++,Pointers,由于使用共享指针,我经常在希望将它们传递给不(必须)拥有对象的函数的情况下运行。因为我知道对象在函数调用期间是有效的,所以我有四个传递指针的选项: 按价值 参照 弱指针 原始指针 起初,我开始大量使用弱指针(因为我已经有了它们),但是一直锁定它们的开销很烦人,会影响性能。现在我考虑通过引用传递原始指针或共享指针。是否有最佳实践 生命周期由堆栈保证。如果您要传递一个弱\u ptr,那么该函数无论如何只需要获取一个共享的\u ptr 您希望通过值传递原始指针,或者通过引用传递实际对象 这两个选项之间
起初,我开始大量使用弱指针(因为我已经有了它们),但是一直锁定它们的开销很烦人,会影响性能。现在我考虑通过引用传递原始指针或共享指针。是否有最佳实践 生命周期由堆栈保证。如果您要传递一个
弱\u ptr
,那么该函数无论如何只需要获取一个共享的\u ptr
您希望通过值传递原始指针,或者通过引用传递实际对象
这两个选项之间的选择取决于所调用函数的语义。如果
nullptr
是函数的有效参数,则传递原始指针。否则,通过引用传递对象。我建议通过const std::shared\u ptr&
传递它们。这有两个好处:
struct Foo { void bar() {} };
class BaseImpl
{
public:
void CallBar(const std::shared_ptr<Foo>& f);
{
do_call_bar(f);
}
private:
virtual void do_call_bar(const std::shared_ptr<Foo>& f) = 0;
};
class DerivedDirectCall : public BaseImpl
{
virtual void do_call_bar(const std::shared_ptr<Foo>& f) override
{
f->bar();
}
};
class DerivedAsyncCall : public BaseImpl
{
virtual void do_call_bar(const std::shared_ptr<Foo>& f) override
{
// assume invoke passes this off
// to be done asynchronously
invoke([f] () { f->bar(); });
}
};
struct Foo{void bar(){};
类BaseImpl
{
公众:
void CallBar(const std::shared_ptr&f);
{
do_call__bar(f);
}
私人:
虚拟无效的调用条(const std::shared\u ptr&f)=0;
};
类DerivedDirectCall:public BaseImpl
{
虚拟void do_call_bar(const std::shared_ptr&f)覆盖
{
f->bar();
}
};
类DerivedAsyncCall:public BaseImpl
{
虚拟void do_call_bar(const std::shared_ptr&f)覆盖
{
//假设调用传递了这个消息
//异步完成
调用([f](){f->bar();});
}
};
根据实现是DerivedDirectCall
还是DerivedAsyncCall
,只有在必要时才会复制共享指针
此外,上面的评论链接。我想澄清的是,我的答案是关于传递智能指针本身的。如果您知道生命周期不一定会延长,那么最好通过引用传递指向的对象(或原始指针,但只需要允许nullptr
参数)
由于使用共享指针,我经常在希望将它们传递给不(必须)拥有对象的函数的情况下运行
你的措辞让它听起来像你的函数真正关心的是被指向的对象,而不是指针。因此,您应该传递对象(通过引用):
void my_func(int&x);
int main()
{
共享\u ptr demo\u ptr=使\u共享(5);
my_func(*demo_ptr);
}
可能的重复请参见@Jeff的问题3如何从共享的\u ptr
获得唯一的\u ptr
?@Jeff我同意。但是您仍然无法将共享的\u ptr
传递给一个需要唯一的\u ptr
的函数,因此它无法解决如何将共享的\u ptr
传递给函数的问题。@Jeff:我不认为智能指针在提取裸指针时会失去作用,因为对象仍然是受管理的。尤其是当一个函数根本不关心所有权的时候。
void my_func(int &x);
int main()
{
shared_ptr<int> demo_ptr = make_shared<int>(5);
my_func(*demo_ptr);
}