【问题标题】:QSharedPointer, how to pass them around, and do I need them?QSharedPointer,如何传递它们,我需要它们吗?
【发布时间】:2015-10-22 19:03:58
【问题描述】:

几天来一直在尝试理解共享指针,感觉好像我无法理解它。不知道是不是太明显了还是太复杂了。首先,谁能给我一个实际使用共享指针的例子。维基百科上的例子对我来说毫无意义。以及如何将共享指针传递给另一个函数或使用共享指针创建对象。那么,你如何传递它以及你会在哪里使用它?任何信息或示例都会很棒。

另外,我有这个问题,我不知道该使用什么。我有这个函数,我分配一个QFile 并将它传递给另一个类中的函数。该函数将文件作为QIODevice*,然后创建一个包含该文件的对象。我想知道这里最好的解决方案是什么,以及如何(如果我应该)在这里使用共享指针?如何使用<QFile> 创建一个共享指针并将其传递到函数采用<QIODevice> 的位置。感觉我根本没有得到共享指针......

我的另一种方法是将QFile 的分配放在QScopedPointer 中。然后我将它传递给类,在创建将存储文件的对象时,我使用QPointerQScopedPointer。在第一个调用函数结束时我应该调用 take() 对吗?

function () {
   QScopedPointer<QFile> item(new QFile("filename"));
   SomeClassObject->doStuff(item.data());
   item.take();
}
---------------------------------
SomeClass::doStuff(QIODevice *item) {
    _currentObject = new MyObject(item); // should _currentObject be a smartpointer?
    ...
}
---------------------------------
class MyObject {
    QPointer<QIODevice> _item;

    ...
    MyObject(QIODevice *item) {  _item = item; }
}

因此,如果“new”抛出异常,我想要一种存储指针的方法和一种在创建过程中处理它们的方法。

【问题讨论】:

    标签: c++ qt pointers shared-ptr qsharedpointer


    【解决方案1】:

    共享指针(以及其他类似的指针包装器)的要点是正确处理指针对象的销毁。那是不必手动确保删除最后一个副本(并且只删除最后一个副本),共享指针会在超出范围时为您处理它。共享部分意味着您可以创建此包装对象(共享指针对象)的副本,并且它将在副本之间“共享”指向对象的指针(就像您制作常规指针的副本一样),并带来额外的好处如上所述。

    至于您的代码,SomeClass::doStuff() 应该有一个 QScopedPointer&lt;QFile&gt; 参数(而不是一个 QIODevice*),因为您将 item 传递给它,它具有那种类型。

    MyObject 的构造函数相同:让它接受QPointer&lt;QIODevice&gt;QSharedPointer&lt;QIODevice&gt; 类型的参数。一般来说,在任何你会使用指针的地方,使用QSharedPointer 代替(使用适当的模板类型)。这将使您免于以后访问已删除对象的麻烦。

    当然,有时您实际上需要原始的QIODevice 指针(例如用于第三方库调用),那么您将使用共享指针对象的data() 成员函数。只需确保您不保留(即存储或以其他方式复制超出必要的内容)返回的原始指针,因为这会削弱共享指针的目的 - 共享指针不会知道您不在下面的额外原始指针共享指针对象的管理。

    编辑: take() 从作用域指针释放指向对象的所有权,因此当作用域指针被销毁时,它不会删除该对象。当您将所有权转让给其他东西时,您不会使用它——比如您的情况是MyObject

    【讨论】:

    • 我认为没有充分的理由将函数的参数设为QScopedPointer。要么将其设为 reference(完全避免使用指针),将其保留为原始指针(允许 all 托管指针类型)或将其设为共享指针(避免复制并使用 @ 987654334@ 共享对象,如果可能的话)。传递一个作用域指针必须通过引用,然后你强制你的用户选择智能指针,这不是一件好事(如果他们使用不同类型的智能指针怎么办?)
    • 我不明白为什么传递共享指针(而不是原始指针)是一个问题(除了强制特定类型之外)。我认为它比传递原始指针更安全(例如,您可以将参数存储到全局容器中,而不必担心调用者会从您下面删除它)。共享指针当然不必通过引用,复制构造器逻辑将确保复制行为适当。你当然可以通过引用传递底层对象,但是为什么要使用指针呢?
    • 它需要一个 QIODevice,因为我不会只将它与 QFile 一起使用。在我的代码中还有其他情况,函数需要采用基本类型
    • @chikuba - 您可以将 QSharedPointer&lt;QFile&gt; 转换为 QSharedPointer&lt;QIODevice&gt;,因此如果您需要基本类型,则可以使用该类型。
    • 但是,当你有多个所有者时,共享指针的目的不就是使用它吗?我最终创建的对象将是它的所有者,没有其他人。我不能在创建对象时只使用作用域指针来处理异常,然后使用它的原始指针,然后在一切完成后将其存储在所有者处吗?
    猜你喜欢
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    相关资源
    最近更新 更多