工厂:如何将临时智能指针传递给函数。 C++

Posted

技术标签:

【中文标题】工厂:如何将临时智能指针传递给函数。 C++【英文标题】:Factories: how to pass temporary smart pointers to functions. C++ 【发布时间】:2018-11-24 06:38:44 【问题描述】:

我有一个班级 Foo

class Foo;

一个工厂返回一个指向它的指针:

std::unique_ptr<Foo> createFoo(); 

而且,由于Herb 告诉我,一个对 Foo 的生命周期没有特殊要求的普通函数应该采用普通的裸指针:

void plainf(Foo* f);

我的客户应该如何正确地做到这一点?

plainF(createFoo());

如果他不得不写,他会不高兴的:

auto someName = createFoo();
plainF(someName.get()); 

【问题讨论】:

我告诉你,不要使用裸指针(是的,你可以引用我的话;)) @hellow 请阅读“Herb”链接。它很有启发性。裸指针确实很好。 好吧,它们在受控环境中很好,每个程序员都知道每个程序员都知道,而不是裸指针意味着观察者指针。我会谨慎行事并使用参考或可选参考。 @YSC: std::experimental::observer_ptr 确定。 :) 和 “没有可选引用;如果程序实例化具有引用类型的可选引用,则程序格式错误” :-( @Jarod42 我很惭愧 :/ 是的,observer_ptr 很好,但自从最后一只恐龙死后它是实验性的...... 【参考方案1】:

如果您不需要 plainF 的参数可以为空,您还可以更改其签名以通过引用获取参数,从而允许稍微不那么冗长的语法:

std::unique_ptr<Foo> createFoo(); 
void plainf(Foo& f);

plainF(*createFoo());

NathanOliver's answer 中提到的所有生命周期注意事项都适用,因此使用起来同样安全。

请注意,这意味着createFoo 永远不会返回空的unique_ptr。因此,如果允许该功能失败,您必须通过其他方式指出该错误,例如。通过抛出异常。

【讨论】:

假设您没有在分配错误的情况下终止程序,则无论如何您都不能创建 noexcept 工厂(在某些特定情况下,您拥有分配的内存并且不使用标准new)。【参考方案2】:

您可以使用get 成员函数,该函数返回指向所拥有对象的原始指针。

plainF(createFoo().get());

createFoo() 创建的临时文件在plainF 完成之前不会超出范围。只要plainF 没有将指针向上传递到范围之外,这是完全安全的。

【讨论】:

@NathanOliver 对,谢谢!那么说plainF“对Foo的生命周期没有要求”仍然有意义吗?实际上它负责不将参数“超出范围”传递? @lubgr 向上传递指针基本上是在玩生命周期。将指针向上传递到范围之外将延长它的生命周期,并且由于它不拥有指针,因此不应对其做出生命周期决定。

以上是关于工厂:如何将临时智能指针传递给函数。 C++的主要内容,如果未能解决你的问题,请参考以下文章

可以将任何原始类型传递给需要指针的函数吗?

如何将智能指针传递给函数?

如何将函数指针传递给成员函数c++?

C++11多线程第三篇:线程传参详解,detach()大坑,成员函数做线程参数

C++11多线程第三篇:线程传参详解,detach()大坑,成员函数做线程参数

C ++:如何将此指针传递给此类?