- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我编写了一个静态工厂方法,它返回一个从另一个数据对象填充的新 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
from a factory 方法很好,应该是推荐的做法。它传达的信息是 (IMO):您现在是该对象的唯一所有者。此外,为了您的方便,该对象知道如何销毁自己。
我认为这比返回一个原始指针要好得多(客户端必须记住如何以及是否处理该指针)。
但是,我不明白您关于释放指针以延长其生命周期的评论。一般来说,我很少看到有任何理由调用 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);
我个人也会添加 typedef
对于返回的指针类型(在本例中为 std::unique_ptr<Foobar>
)和/或使用的删除器(在本例中为 std::default_deleter)到您的工厂对象。如果您稍后决定更改指针的分配,这将变得更容易(因此需要使用不同的方法来销毁指针,这将作为 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);
关于c++ - 为原始指针(如所有权语义)返回 unique_ptr 的坏习惯?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8719119/
我正在使用 tcod-rs。用于绘制到 RootConsole 的每个方法都采用一个可变引用。中央循环是一个 while 循环,它等待窗口关闭、清除屏幕、绘制,然后刷新。 “检查窗口关闭”方法也采用可
我写了一个具有这种形式的函数: 结果 f(const IParameter& p); 我的意图是这个签名将明确表明函数没有取得参数 p 的所有权。 问题是 Result 将保留对 IParameter
这个问题在这里已经有了答案: 关闭 9 年前。 Possible Duplicate: What is a smart pointer and when should I use one? 我正在阅
假设我有一个类: class Scheduler { Scheduler(JobService *service); AddJob(JobID id, ISchedule *sched
我试图弄清楚所有权如何与函数 CVMetalTextureGetTexture 一起工作: CVMetalTextureRef textureRef; // ... textureRef is cre
这个问题在这里已经有了答案: Should we pass a shared_ptr by reference or by value? (10 个答案) 关闭 4 年前。 例如 class A {
我正在做一个附带项目,我需要根据他的 gmail 帐户或任何其他参数来验证 channel 是否属于某个用户……这基本上是为了避免假帐户。是否可以? 最佳答案 是的, 跟随 youtube 记录的链接
我在使用Core Foundation Array时发现了一个奇怪的问题!这是代码片段 fname = CFStringCreateWithFormat(kCFAllocatorDefault, NU
有没有一种方法可以设置在 apache 下运行的 php 来创建文件夹,该文件夹的文件夹属于创建它的程序的所有者,而不是由 apache 拥有? 使用 word press 它会创建要上传到的新文件夹
我编写了以下函数来使用 boost.date_time 获取日期/时间字符串. namespace bpt = boost::posix_time; string get_date_time_stri
我在使用 Docker 容器时遇到了一个有点烦人的问题(我在 Ubuntu 上,所以没有像 VMWare 或 b2d 这样的虚拟化)。我已经构建了我的镜像,并且有一个正在运行的容器,它有一个来 sel
根据大多数示例,逻辑上最少有 3 个组织 ( org1, org2, orderer )。 实际上只有 2 个物理组织 ( org1, org2 )。任一组织或约定的第 3 方必须移交订购者组织的职责
我开始学习 Rust,在进行实验时,我发现所有权如何应用于我不理解的元组和数组的方式有所不同。基本上,以下代码显示了差异: #![allow(unused_variables)] struct Inn
我们有一个应用程序,其表单上有许多组件(面板、选项卡、编辑、组合框等)。但根据用户配置文件,其中大多数可以自动填充和/或不可见。因此,用户可以更快地完成工作。 问题:是否有更简单的方法可以在运行时创建
我有以下代码片段: fn f u32>(c: T) { println!("Hello {}", c()); } fn main() { let mut x = 32; let
我想执行示例中的代码: require_once 'google-api-php-client/vendor/autoload.php'; $client = new Google_C
这个问题在这里已经有了答案: What is move semantics? (11 个答案) 关闭 3 年前。 我有一个看起来像这样的构造函数: Thing::Thing(std::vector
我们正在使用服务帐户从服务器上传文件,但它已达到其存储配额限制。所有文件都已添加到另一个用户(具有 100 Gb 存储配额的 @gmail.com 帐户)创建的文件夹下,但上传的所有文件均归该服务帐户
我正处于 this question 中描述的 sme 情况。 .那个提问者找到的解决方案是 Full access !== Owner. I need to read the documentati
我正处于 this question 中描述的 sme 情况。 .那个提问者找到的解决方案是 Full access !== Owner. I need to read the documentati
我是一名优秀的程序员,十分优秀!