为什么要在 c++ 中创建一个指向基元类型的唯一指针?

Why would you ever make a unique pointer to a primitive type in c++?

本文关键字:类型 指针 唯一 一个 c++ 创建 为什么      更新时间:2023-10-16

我刚刚找到了这段代码,谁知道它来自哪里或什么时候,但它是一个函数的结尾,而不是返回一个简单的int64_t类型,它对它进行了unique_ptr。

我只是想知道是否有人可以解释这种用法的价值?

return std::make_unique<int64_t>(off);

更新:

它不是以这种方式使用的,但正如我在下面评论的那样,指向原始与仅指向原始的指针的一种可能用途是您可以将指针设置为 null,从而在错误或不可用时向整数添加一个标志。

将基元类型的变量声明为

int64_t foo;

表示foo被放置在堆栈上并且是块范围的(即,它在块的末尾超出范围)。更正式地使用C++术语,它具有自动存储持续时间:

对象在封闭代码块的开头分配,在末尾解除分配。所有本地对象都有此存储持续时间,但声明为静态、外部或thread_local的对象除外。

另一方面,使用unique_ptr...

auto foo = std::make_unique<int64_t>(off);

。为堆上的int64_t分配内存。形式上,它具有动态存储持续时间:

使用动态内存分配函数为每个请求分配和取消分配对象。

您可以通过声明指向int64_t的指针并使用new来自己执行此操作:

int64_t *foo = new int64_t;

但是你必须确保你不要忘记delete那个指针。这就是unique_ptr的用武之地。当指针超出范围时,它会删除它拥有的指针。这是雷伊。您还可以将所有权转移到其他unique_ptr实例。

可以通过将unique_ptr移动到其他位置来延长指向unique_ptr整数的生存期。

自动存储整数的生存期在其作用域或封闭对象结束时结束。

如果不仅整数的值很重要,而且身份也很重要,那么unique_ptr可以解决原始整数无法解决的问题。

例如,我可以将该unique_ptr与线程配对。 线程可以负责将信息写入所述unique_ptr

线程是可移动的;原始整数不是。 因此,两者的语义不一致,因此您不能将线程和基元 int 推入结构或类并使用默认的移动操作。

如果对基元类型使用线程和唯一的 ptr,则可以将其扔到结构中并使用默认的移动操作,它们就可以工作。

您可以使用共享 ptr,但是如果我们假设两个对象(唯一 ptr 和线程)绑定在一个结构中,其中线程首先被销毁,则不需要其他共享,并且共享 ptr 会产生开销成本。 此外,如果公开共享 ptr 会导致所有权跟踪地狱。 共享 PTR 的运行时成本是第二次分配和原子增量/递减的混合,导致并发争用成本。 编译时成本是所有权语义变得比唯一的 ptr 更复杂。

这更有可能是一个糟糕的设计决策,但有可能的原因不是。