上下文
下面的错误似乎在告诉我我无法从此GET函数中返回unique_ptr
称为m_head
。我只想在不转移所有权的情况下返回unique_ptr
m_head
。
从那以后,我一直完全避免将原始指针引入智能指针,因为原始指针并不例外安全,让内存管理开销和我所知道的其他问题。也许有些情况下,我应该在小范围中简要使用它们?
在这种情况下,我认为我需要转移所有权而不是当前的方法。相反,我应该通过unique_ptr
管理对象,创建一个新的shared_ptr
来管理对象,然后返回shared_ptr
,但需要一些确认。我认为可能是这种情况,因为std :: unique_ptr文档说:
unique_ptr对象拥有其指针的独特性:没有其他设施 照顾删除对象,因此没有其他托管指针 应该指向其托管对象,因为 unique_ptr对象删除其托管对象而无需进入说明其他指针是否仍然指向同一对象,,因此留下了任何其他指向指向的指针 无效位置。
错误
`function "std::unique_ptr<_Ty, _Dx>::unique_ptr(const std::unique_ptr<_Ty, _Dx> &)
[with _Ty=mrobsmart::LinkedList::Node, _Dx=std::default_delete<mrobsmart::LinkedList::Node>]"
(declared at line 2337 of "C:Program Files (x86)Microsoft Visual Studio2017EnterpriseVCToolsMSVC14.15.26726includememory")
cannot be referenced -- it is a deleted function
代码
#include <memory>
class LinkedList
{
private:
std::unique_ptr<Node> m_head;
public:
LinkedList(int data) {
m_head = std::make_unique<Node>(data);
}
const std::unique_ptr<Node> get_head() { return m_head; }
};
我只想在不转移所有权的情况下返回我的unique_ptr m_head。
这是不可能的。unique_ptr
的设计围绕着每一步转移其所有权的行为。
请注意,由于原始指针并不例外,我一直在避免使用原始指针应该在小范围中短暂使用它们?
原始指针不是邪恶的。将它们用作纯参考/间接是一个完全有效的用例 - 不涉及所有权,内存管理或异常安全。
当然,也可以返回C 参考。您是选择指针还是参考可以取决于该值是否可以为null,但最终也是代码样式的问题。
所以,任何一个(重要: const
- qualify函数(:
const Node* get_head() const { return m_head.get(); }
const Node& get_head() const { return *m_head; }
问题背后的问题。也许您正在尝试在不应该使用的情况下使用unique_ptr
。我同意应该避免原始指针,但是除了原始指针外,还有其他选择。
std::unique_ptr
的两个重要属性是:
- 表示未设置值的值(即
null
(。 - 转移所有权的能力。
如果您不需要,最好将Node
值直接存储在m_head
,即:
#include <memory>
class LinkedList
{
private:
Node m_head;
public:
LinkedList(int data) : m_head(data) {}
const Node& get_head() { return m_head; }
};
如果代码示例是真实方案的简化版本,其中m_head
不能设置"设置",我们将需要其他解决方案,例如。std::optional
。
std::optional
和std::unique_ptr
都可以表示未设置的值。但是,std::optional
不支持所有权转移。
如果您想防止所有权转移,那么使用这种不可能的类型是将您的意图传达给同事和未来自我的好方法。代码将更改为:
#include <memory>
class LinkedList
{
private:
std::optional<Node> m_head;
public:
LinkedList(int data) : m_head(Node(data)) {}
// some other code which can cause m_head to be empty
const std::optional<Node> get_head() { return m_head; }
};