C++ 返回原始指针式所有权语义的唯一_ptr的错误做法?

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(); 我的问题分为两部分: 这种方法是否传达了

我编写了一个静态工厂方法,它返回从另一个数据对象填充的新Foobar对象。我最近一直沉迷于所有权语义,我想知道通过让这个工厂方法返回一个
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
    之上,那么为什么要为一些可能不必要的功能牺牲性能呢m
    unique\u ptr
    实际上没有任何好处调用方并不严格拥有指针。调用方的
    unique\u ptr
    对象拥有指针:p@Andr共享的ptr可以从一个唯一的ptr构建,但反过来通常是不可能的
    很抱歉,这可能会造成误导或混淆。这段新代码将进入一个相当大的现有应用程序(100-200万行C++),该应用程序不使用任何智能指针(COM除外)。我知道,如果旧代码使原始指针有效地“必需”,我的团队中的其他人会担心是否没有合理的方法获取原始指针。当然,我会给出适当的警告,并在可能的情况下建议坚持使用unique_ptr/shared_ptr。我非常喜欢你的typedef想法,它使你的答案与James McNellis不同。谢谢你的见解。