如何将 std::unique_ptr 初始化为引用

Posted

技术标签:

【中文标题】如何将 std::unique_ptr 初始化为引用【英文标题】:How do you initialise a std::unique_ptr to a reference 【发布时间】:2021-06-23 19:19:38 【问题描述】:

使用原始指针我可以做到:

int x = 10;
int* y = &x;

x = 20;
std::cout << *y; //prints 20

但是,我正在努力模仿 std::unique_ptr 的相同行为。我试过了:

int x = 10;

std::unique_ptr<int> y = std::make_unique(&x); //doesnt compile
std::unique_ptr<int> y = std::make_unique<int>(&x); //doesnt compile
std::unique_ptr<int&> y = std::make_unique(x); //doesnt compile
std::unique_ptr<int> y = std::make_unique<int&>(&x); //doesnt compile

std::unique_ptr<int> y = std::make_unique<int>(x); //compiles but prints y = 10, which is not the desired behaviour

我确信有办法,所以任何帮助表示赞赏。谢谢。

【问题讨论】:

@RemyLebeau 这是有道理的,所有关于不使用原始指针的讨论都让我明白了。耸耸肩。谢谢:) 一般来说使用原始指针并没有错,只要它们不用于处理所有权语义。不再推荐直接使用new/delete,代替提供更强所有权语义的标准容器和智能指针。两种不同的东西。 请注意,如果您在 C++ 中通过反复试验进行编程,您将度过一段糟糕的时光。未定义行为潜伏在黑暗中,等待突袭毫无戒心的程序员。文档是你的朋友。 @alterigel 我正在阅读 cpp 参考,但它让我发疯了,因为它没有显示如何从参考中初始化唯一的 ptr! doh ...您不能这样做,因此它不在cpp参考中。应该已经阅读了小文本。 【参考方案1】:

unique_ptr 是关于管理动态分配内存的生命周期。

也就是说

std::unique_ptr<int> y = std::make_unique<int>(x);

表示为整数分配内存,复制 x 的值到其中,当 y 超出范围时请释放该内存。

在您的示例中,您对管理已分配存储的生命周期不感兴趣,您只想要另一个“查看”为 x 存储的内容。这不是 unique_ptr 的设计目的。

【讨论】:

【参考方案2】:

第一个代码中没有动态分配,所以根本不需要尝试用unique_ptr模拟它。

unique_ptr 管理一个指向使用 new 分配的对象的指针,并且当 unique_ptr 超出范围时将 delete 该对象。你不能让unique_ptr 充当对它不拥有的外部对象的引用。

话虽如此,如果您确实希望两个智能指针指向内存中的同一个对象,请使用shared_ptr 而不是unique_ptr,例如:

#include <memory>

auto x = std::make_shared<int>(10);
auto y = x;

*x = 20;
std::cout << *y; //prints 20

Demo

【讨论】:

你可以让唯一的ptr“管理”地址,并给它一个noop删除器。毫无意义,但它可以满足 OP 的要求 @AndyG 在那种情况下,它并不比std::reference_wrapper 好。

以上是关于如何将 std::unique_ptr 初始化为引用的主要内容,如果未能解决你的问题,请参考以下文章

将多态成员变量实例化为适当的类型

[C++11]独占的智能指针unique_ptr的初始化和使用

如何将 std::sort() 与 std::unique_ptr<[]> 一起使用?

如何初始化一个unique_ptr

如何创建一个可以将 std::unique_ptr 作为模板参数正常工作的容器?

vector<unique_ptr> 的初始化失败并出现复制错误