Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 堆分配对象是否有从不为null的唯一所有者?_C++_Architecture_Null_Heap_Smart Pointers - Fatal编程技术网

C++ 堆分配对象是否有从不为null的唯一所有者?

C++ 堆分配对象是否有从不为null的唯一所有者?,c++,architecture,null,heap,smart-pointers,C++,Architecture,Null,Heap,Smart Pointers,目前,我正在存储std::unique_ptrs的集合,以堆分配给多态类型的对象: struct Foo { virtual ~Foo() = default; }; Collection<std::unique_ptr<Foo>> foos; structfoo{ virtual~Foo()=默认值; }; 收集食物; 我需要的基本界面是将Foo的所有者放入/从foos中取出。存储在foos中的对象永远不应该是nullptr,因此我想用编译时检查替换运行时ass

目前,我正在存储
std::unique_ptr
s的集合,以堆分配给多态类型的对象:

struct Foo {
  virtual ~Foo() = default;
};
Collection<std::unique_ptr<Foo>> foos;
structfoo{
virtual~Foo()=默认值;
};
收集食物;
我需要的基本界面是将
Foo
的所有者放入/从
foos
中取出。存储在
foos
中的对象永远不应该是
nullptr
,因此我想用编译时检查替换运行时
assert(owner_take)
。此外,我希望能够在可能需要可空所有者的上下文中使用非空所有者

可能,我需要存储类似于
unique\u ref
的内容,但是如何从
foos
中提取一个呢?我不想要副本,我想要存储的对象本身,因此
owner->clone()
不是解决方案。我也不能
std::move(owner)
,因为“唯一引用”的状态在之后将无效

是否有一个干净的设计决策

堆分配对象是否有从不为null的唯一所有者

标准库中没有此类类型

实现这种类型是可能的。只需定义一个具有唯一_ptr成员的类型,并将默认构造函数标记为已删除。您也可以将
std::nullptr\u t
中的构造函数标记为已删除,以便在编译时防止从
nullptr
中构造

无论您是从外部指针构造,还是在构造函数中分配,都无法在运行时检查null

堆分配对象是否有从不为null的唯一所有者

标准库中没有此类类型

实现这种类型是可能的。只需定义一个具有唯一_ptr成员的类型,并将默认构造函数标记为已删除。您也可以将
std::nullptr\u t
中的构造函数标记为已删除,以便在编译时防止从
nullptr
中构造



无论您是从外部指针构造,还是在构造函数中分配,都无法在运行时检查null。

如果在never null唯一所有者中不允许非所有者状态,则您永远无法从该状态移动,因为该状态没有任何有效状态。所以这样的类型总是不可移动的。这真的是你想要的吗?集合是否可以与不可移动的类型一起工作?作为折衷方案,您可以使自己的nullptr抛出唯一的\u ptr,当它持有一个nullptr并试图访问它所生成的nullptr时抛出,或者如果尝试使用nullptr构造,则抛出。(例如,在从内部移出内脏后,留下一个空外壳。)@walnut如果我还建议了其他一些在需要时仍然提供编译时不可空性保证的方法,那还是不错的。但是你的集合能处理不可移动的类型吗?例如,
std::vector
不能。@Eljay我恐怕它太接近我想要避免的
assert(owner)
。如果你不允许在never-null唯一所有者中使用非所有者状态,那么你就永远不能从中移动,因为没有任何有效的状态。所以这样的类型总是不可移动的。这真的是你想要的吗?集合是否可以与不可移动的类型一起工作?作为折衷方案,您可以使自己的nullptr抛出唯一的\u ptr,当它持有一个nullptr并试图访问它所生成的nullptr时抛出,或者如果尝试使用nullptr构造,则抛出。(例如,在从内部移出内脏后,留下一个空外壳。)@walnut如果我还建议了其他一些在需要时仍然提供编译时不可空性保证的方法,那还是不错的。但是你的集合能处理不可移动的类型吗?例如,
std::vector
不能。@Eljay我恐怕它太接近我想要避免的
assert(owner)
。引用呢
T&
保证永远不会为空。@传递\u不是在法律代码中,但不幸的是它很容易编写。@user4581301实际上,像您提供的例子就是我在这里尝试使用引用而不是指针的原因:我可以确定它们不是空的。如果我的问题有一个包含所有预期功能的答案,我可以将指针的使用限制在值实际上可以为空的情况下,因此总是检查这种特殊情况并不困难。@passing_through我强烈建议不要通过引用获得对象地址的所有权。太容易意外地传递非所有权对象,如自动对象。@eerorika你说得对:正是因为这种危险,我想要一个特殊的伪引用所有者类(而不是
&
)来拥有堆上的对象。那么引用呢
T&
保证永远不会为空。@传递\u不是在法律代码中,但不幸的是它很容易编写。@user4581301实际上,像您提供的例子就是我在这里尝试使用引用而不是指针的原因:我可以确定它们不是空的。如果我的问题有一个包含所有预期功能的答案,我可以将指针的使用限制在值实际上可以为空的情况下,因此总是检查这种特殊情况并不困难。@passing_through我强烈建议不要通过引用获得对象地址的所有权。太容易意外地传递非所有权对象,如自动对象。@eerorika你说得对:正是因为这种危险,我想要一个特殊的伪引用所有者类(而不是
&
)来拥有堆上的对象。