你为什么要在 C++ 中创建一个指向原始类型的唯一指针?

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

我刚找到这段代码,谁知道它来自何时何地,但它是一个函数的结尾,它不是返回一个简单的 int64_t 类型,而是返回一个 unique_ptr .

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

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

更新:

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

将原始类型变量声明为

int64_t foo;

表示foo入栈并且是block-scoped (i.e., it goes out of scope at the end of the block). More formally using C++ terms it has automatic storage duration:

The object is allocated at the beginning of the enclosing code block and deallocated at the end. All local objects have this storage duration, except those declared static, extern or thread_local.

另一方面,使用 unique_ptr...

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

... 为堆上的 int64_t 分配内存。正式地,它有 dynamic storage duration:

The object is allocated and deallocated per request by using dynamic memory allocation functions.

您可以通过声明指向 int64_t 的指针并使用 new:

来自己完成此操作
int64_t *foo = new int64_t;

但是你必须确保你不会忘记delete那个指针。那就是 unique_ptr 进来的地方。它在超出范围时删除它拥有的指针。这是RAII。您还可以将所有权转移到另一个 unique_ptr 实例。

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

自动存储整数的生命周期在其范围或封闭对象结束时结束。

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

例如,我可以将 unique_ptr 与线程配对。线程可以负责写信息到表示unique_ptr.

线程是可移动的;原始整数不是。所以两者的语义不一致,所以你不能将线程和原始 int 推入结构或 class 并使用默认移动操作。

如果您使用一个线程和一个原始类型的唯一 ptr,您可以将它扔到一个结构中并使用默认的移动操作并且它们可以工作。

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

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