C++ 返回原始指针式所有权语义的唯一_ptr的错误做法?
我编写了一个静态工厂方法,它返回从另一个数据对象填充的新Foobar对象。我最近一直沉迷于所有权语义,我想知道通过让这个工厂方法返回一个C++ 返回原始指针式所有权语义的唯一_ptr的错误做法?,c++,smart-pointers,unique-ptr,ownership-semantics,C++,Smart Pointers,Unique Ptr,Ownership Semantics,我编写了一个静态工厂方法,它返回从另一个数据对象填充的新Foobar对象。我最近一直沉迷于所有权语义,我想知道通过让这个工厂方法返回一个unique\u ptr,是否传达了正确的信息 class Foobar { public: static unique_ptr<Foobar> factory(DataObject data); } Foobar* myFoo = Foobar::factory(data).release(); 我的问题分为两部分: 这种方法是否传达了
unique\u ptr
,是否传达了正确的信息
class Foobar {
public:
static unique_ptr<Foobar> factory(DataObject data);
}
Foobar* myFoo = Foobar::factory(data).release();
我的问题分为两部分:
唯一\u ptr
而不是原始指针是否是一种“错误做法”std::unique\u ptr
唯一地拥有它所指向的对象。上面写着“我拥有这个物体,其他人没有。”
这正是您想要表达的:您说的是“此函数的调用方:您现在是此对象的唯一所有者;请随意处理它,它的生命周期是您的责任。”> P>它准确地传达了正确的语义,是我认为C++中所有工厂都应该工作的方式:<代码> STD::UNQuYGYPTR 不施加任何所有权语义,而且非常便宜。 < P>返回“代码> STD::UnQuyJPPT//C>从工厂方法是很好的,应该是推荐的做法。它传达的信息是(IMO):您现在是该对象的唯一所有者。此外,为了您的方便,对象知道如何销毁自身。 我认为这比返回原始指针要好得多(客户机必须记住如何以及是否处理该指针) 但是我不理解你关于释放指针以延长其生命周期的评论。一般来说,我很少看到有任何理由对smartpointer调用
release
,因为我认为指针应该始终由某种RAII结构管理(我调用release
的唯一情况是,在我做了一些保证额外清理的事情之后,将指针放在不同的管理数据结构中,例如unique\u ptr
,使用不同的删除器)
因此,只要客户机需要对象(或者如果需要指针的多个副本,则客户机可以(并且应该)简单地将唯一\u ptr
存储在某个地方(例如另一个唯一\u ptr
,它是从返回的对象移动构造的)。因此客户端代码应该更像这样:
std::unique_ptr<FooBar> myFoo = Foobar::factory(data);
//or:
std::shared_ptr<FooBar> myFoo = Foobar::factory(data);
class Foobar {
public:
typedef std::default_deleter<Foobar> deleter;
typedef std::unique_ptr<Foobar, deleter> unique_ptr;
static unique_ptr factory(DataObject data);
}
Foobar::unique_ptr myFoo = Foobar::factory(data);
//or:
std::shared_ptr<Foobar> myFoo = Foobar::factory(data);
您正在返回一个unqiue_ptr来告诉客户端他们拥有指针?这与我的预期正好相反(因为他们必须显式地拥有唯一指针)。您可能希望改用移动语义(如果您能够使用C++11)。这样,用户就可以决定如何延长工厂创建的对象的生命周期。@evnu这是自动为您完成的,不是吗?@SethCarnegie是的。我想知道为什么bkuhns不返回类型为
Foobar
的对象来转移所有权。我只想重申一点回答:而不是使用release()
,客户端代码应该将指针保持为智能指针,如果需要共享所有权,则将其转换为共享\u ptr
,否则将其保留为唯一\u ptr
。确实如此,但为什么不让它返回std::shared\u指针呢?它实现了相同的效果,但允许指针的多个副本。@AndréCaron:如果您只想将所有权转移给调用者,为什么要强制使用std::shared_ptr
?如果调用者愿意,让调用者将对象的所有权交给std::shared_ptr
(或者另一种智能指针,如果调用者愿意)@AndréCaron:原因基本上是性能。工厂不知道客户是否会将std::shared_ptr
添加的功能置于std::unique_ptr
之上,那么为什么要为一些可能不必要的功能牺牲性能呢munique\u ptr
实际上没有任何好处调用方并不严格拥有指针。调用方的unique\u ptr
对象拥有指针:p@Andr共享的ptr可以从一个唯一的ptr构建,但反过来通常是不可能的
很抱歉,这可能会造成误导或混淆。这段新代码将进入一个相当大的现有应用程序(100-200万行C++),该应用程序不使用任何智能指针(COM除外)。我知道,如果旧代码使原始指针有效地“必需”,我的团队中的其他人会担心是否没有合理的方法获取原始指针。当然,我会给出适当的警告,并在可能的情况下建议坚持使用unique_ptr/shared_ptr。我非常喜欢你的typedef想法,它使你的答案与James McNellis不同。谢谢你的见解。