Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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++ C++;11指向唯一\u ptr的非所有权引用/指针?_C++_Pointers_Reference_Unique Ptr - Fatal编程技术网

C++ C++;11指向唯一\u ptr的非所有权引用/指针?

C++ C++;11指向唯一\u ptr的非所有权引用/指针?,c++,pointers,reference,unique-ptr,C++,Pointers,Reference,Unique Ptr,这不是一个“如何做”的问题,而是“如何以正确的方式做” 我正在Qt中开发一个编辑器,其中不同的小部件显示子部件及其(成员)变量。这些小部件中的每一个都应该包含一个指向已编辑子部件的引用/指针,以显示和更改其成员变量 第一次尝试是我用简单的原始指针指向所用对象的老ANSI C方式学习(现在仍然有点死板)。它工作得很好,但由于C++11标准支持智能指针,因此建议使用它们,我正在尝试使用它们 问题是,我不太确定在这种情况下使用它们的“最佳方式”是什么。。。 在阅读和其他一些文章后,我得出了不同的结论:

这不是一个“如何做”的问题,而是“如何以正确的方式做”

我正在Qt中开发一个编辑器,其中不同的小部件显示子部件及其(成员)变量。这些小部件中的每一个都应该包含一个指向已编辑子部件的引用/指针,以显示和更改其成员变量

第一次尝试是我用简单的原始指针指向所用对象的老ANSI C方式学习(现在仍然有点死板)。它工作得很好,但由于C++11标准支持智能指针,因此建议使用它们,我正在尝试使用它们

问题是,我不太确定在这种情况下使用它们的“最佳方式”是什么。。。 在阅读和其他一些文章后,我得出了不同的结论:

第一种方法是使用
*unique_ptr
,因为编辑的对象显然是创建和删除其子对象的所有者。这些小部件只是指用来显示或更改它们的子部件。 问题是小部件应该如何引用子部件

现在,我仍然在使用
unique\u ptr
get()
方法得到的原始指针,但这对我来说似乎有点缺陷。 我仍然可以意外地调用指针上的delete并取消智能指针的好处

第二种方法是使用
共享\u ptr
,因为许多对象引用子对象并对其进行编辑。另外,在一个小部件中意外删除它也不会造成任何伤害,因为它仍然属于其他对象。 问题是他们拥有它。当我想从编辑的对象中删除它时,我还必须在它真正消失之前向所有小部件发出删除它的信号。(这似乎又有缺陷,而且容易出错)


我对这两种方式都不满意。是否有一种干净(er)的方式来指向对象的
唯一\u ptr
子对象?还是我缺少了一个完全不同的更好的方法来解决这个问题?

你想用一个
共享的\u ptr
来代替你的
唯一的\u ptr
,用
弱的\u ptr
来代替你的原始指针。这会给你想要的东西。
弱\u ptr
不会干扰已编辑对象删除基础对象的能力

您的用例不会直接转化为需求(如果其他人在您编辑小部件时删除了它怎么办?),但我假设您不需要除了裸指针之外的任何东西

标准库不提供任何严格的指针观察器类。在观察员实体中:

  • 本机类型的可空、可变指针(
    T*
  • 本机类型(
    T&
    )的不可空、不可变引用
  • 类类型(
    std::reference\u wrapper
    )的不可空、可变引用/代理
  • 指向托管对象的可空、自验证、可变指针(
    std::weak_ptr
如果您想要一个指向非托管对象的不可为空、可变的指针,这是一个相当合理的要求,那么您可以使用自己的指针


但是赤裸裸的指针并没有那么糟糕。唯一的区别是它可以是代码> NulLPTR < /C>,它在名称空间<>代码> STD中没有一个好的、长的、显式的名称。

< P>如果您使用QT,您可以考虑使用QT智能指针代替STD::智能指针:

或对于QoObject:

  • (或
    QWeakPointer
    ,尤其是在Qt4中)
或实现写时复制数据共享、Qt容器和QString样式:

还有其他的指针类,但是上面的一些最有可能实现您想要的功能。同样重要的是,如果您的数据在Qt容器类中,
QStrings
或诸如此类,它们使用写时复制语义处理自己的内存,通常应该作为普通值(有时作为引用)而不是指针进行传递


但最重要的是,不要对具有父对象的QObject使用
std::unique_ptr
std::shared_ptr
,因为如果父对象先删除子对象,那么std::指针将再次删除它,导致程序崩溃(另一种方式可以,子对象将通知其父对象它已删除)。换句话说,如果混合使用QObject和std::指针,很可能会出现细微的bug,所以不要这样做。您的问题不清楚您是否正在这样做,只是以防万一。

有一个针对的建议,它是一个非所有者指针。基本上,它是一个
T*
,上面写着“哦,顺便说一句,我对这些数据没有任何所有权”

在这种情况下,如果
unique\u ptr
消失,您必须管理观察/被动/哑指针被重置——半手动生命周期管理。使用原始的
T*
,其名称表明它是非所有权的,同样也可以在拥有上述内容之前使用

执行上述操作有很多好处,尤其是当您拥有具有依赖生存期的对象时

如果不这样做,则
共享\u ptr
弱\u ptr
工作。但是,请注意,任何
弱\u ptr
的人都可以创建一个新的
共享\u ptr
,它可以将共享对象的生存期延长到原始
共享\u ptr
之外。这必须发生,因为存在一种竞争条件,即
弱\u ptr
的用户确保其数据有效,然后使用它,但在使用之前,
共享\u ptr
的数据会被销毁

因此
弱\u ptr
必须能够防止
共享\u ptr
被破坏(在多线程上下文中阻塞,导致它在单线程上下文中以某种方式“失败”)。在这种情况下,“Fail”包括延长生存期,这解决了多线程和单线程问题

(单线程问题是,如果您验证
弱\u ptr
是否正常,请执行导致
共享\u ptr
重置的操作,然后