为原始指针(如所有权语义)返回unique_ptr的不良做法
Bad practice to return unique_ptr for raw pointer like ownership semantics?
我编写了一个静态工厂方法,该方法返回从另一个数据对象填充的新Foobar对象。我最近痴迷于所有权语义,想知道我是否通过让这个工厂方法返回unique_ptr
来传达正确的信息。
class Foobar {
public:
static unique_ptr<Foobar> factory(DataObject data);
}
我的目的是告诉客户端代码他们拥有指针。如果没有智能指针,我只会返回Foobar*
.但是,我想强制删除此内存以避免潜在的错误,因此unique_ptr
似乎是一个合适的解决方案。如果客户端想要延长指针的生存期,他们只需在获得unique_ptr
后调用.release()
。
Foobar* myFoo = Foobar::factory(data).release();
我的问题分为两部分:
- 这种方法是否传达了正确的所有权语义?
- 这是返回
unique_ptr
而不是原始指针的"不良做法"吗?
从工厂方法返回std::unique_ptr
很好,应该是一种推荐的做法。它传达的信息是(IMO(:您现在是此对象的唯一所有者。此外,为了您的方便,物体知道如何摧毁自己。
我认为这比返回原始指针要好得多(客户端必须记住如何以及是否处理此指针(。
但是,我不明白您关于释放指针以延长其使用寿命的评论。一般来说,我很少看到任何理由在 smartpointer 上调用 release
,因为我认为指针应该始终由某种 RAII 结构管理(我调用release
的唯一情况是将指针放在不同的管理数据结构中,例如具有不同删除器的unique_ptr
, 在我做了一些值得额外清理的事情之后(。
因此,客户端可以(并且应该(简单地将unique_ptr
存储在某个地方(例如另一个unique_ptr
,它已从返回的构造(,只要他们需要对象(或shared_ptr
,如果他们需要指针的多个副本(。所以客户端代码应该看起来更像这样:
std::unique_ptr<FooBar> myFoo = Foobar::factory(data);
//or:
std::shared_ptr<FooBar> myFoo = Foobar::factory(data);
就个人而言,我还会为返回的指针类型(在本例中为 std::unique_ptr<Foobar>
(和/或使用的删除器(在本例中为 std::d efault_deleter(添加一个typedef
到您的工厂对象。如果您稍后决定更改指针的分配,这会更容易(因此需要一种不同的方法来销毁指针,该方法将作为第二个模板参数 std::unique_ptr
可见(。所以我会做这样的事情:
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);
std::unique_ptr
唯一拥有它指向的对象。 它说"我拥有这个对象,没有其他人拥有。
这正是你想表达的:你说"这个函数的调用者:你现在是这个对象的唯一所有者;随心所欲地使用它,它的一生是你的责任。
它准确地传达了正确的语义,也是我认为C++所有工厂都应该工作的方式:std::unique_ptr<T>
不强加任何类型的所有权语义,而且非常便宜。
- 为什么 std::unique 不调用 std::sort?
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 生成"unique"矩阵
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 我对 std::unique(算法)C++有问题
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- std::shared_ptr::unique(),复制和线程安全
- 如何在C++03中用自定义谓词调用std::unique
- C++中的指针否定 (!ptr == NULL)
- C++14 unique_ptr并使用已删除的函数'std::unique-ptr' unique_ptr错误