泛化共享指针和 QSharedPointer::data() vs shared_ptr::get()?

Posted

技术标签:

【中文标题】泛化共享指针和 QSharedPointer::data() vs shared_ptr::get()?【英文标题】:Generalizing shared pointers and QSharedPointer::data() vs shared_ptr::get()? 【发布时间】:2012-06-22 04:33:40 【问题描述】:

我创建了a Qt library,它建立在QSharedDataPointerQSharedData 这样的长期抽象之上。所以当我需要一个普通的共享指针时,为了保持一致性,使用QSharedPointer 是有意义的。

我现在在 C++11 项目中使用它。为了使代码更标准,我将其所有本地子系统切换到shared_ptr

库本身中的 C++11 依赖项不一定是可取的,因此感觉您应该能够选择要使用的共享指针类型。作为前进的第一步,我尝试了Flexibility of template alias in C++0x 中建议的这种方法(诚然,它本身就是一个 C++11 依赖项,但我可以通过非 C++11 构建中的编译器标志使用预处理器)

#if THINKERQT_USE_STD_SHARED_PTR

#include <memory>
template<class T>
using shared_ptr_type = std::shared_ptr<T>;

#else

#include <QSharedPointer>
template<class T>
using shared_ptr_type = QSharedPtr<T>;

#endif

不幸的是,指针类为方法选择了不同的名称。值得注意的是,访问包含的指针是由 shared_ptr 中的 .get() 和 QSharedPointer 中的 .data() 完成的。

我打算制作一个提取器,某种shared_ptr_type_get&lt;&gt;,但随后注意到可以有效地实现相同的事情(在包含的指针不为空的情况下,我可以通过布尔强制测试是否为空) :

&(*ptr)

如果您正在阅读代码,这会有点慢,并且有人可能会尝试优化(然后很快就会发现这是行不通的)。但除了 WTF 因素之外,它似乎无害……是吗?

【问题讨论】:

学究式地,&amp;*ptr 在指针为空时给出未定义的行为。 @MikeSeymour 是的。但是就像我说的那样,如果需要,您可以 static_cast&lt;bool&gt; QSharedPointer 和 shared_ptr 来测试 null;他们对此有相同的支持。 【参考方案1】:

我也在我的一个项目中使用它,除了您已经注意到的可读性之外,使用它没有任何问题。正如 Mike Seymour 所指出的,您应该始终首先检查 ptr 不是空指针。

我在大多数情况下使用以下成语:

if( shared_ptr_type ptr = funcReturnsSharedPtr() )

    funcAcceptsRawPtr(&*ptr);

几乎可以保证,无论您为shared_ptr_type 使用哪种共享指针类型,它都能正确编译和运行,因为任何合理的共享指针类都会重载operator*

【讨论】:

+1 很高兴看到我不是唯一一个。 (我喜欢在代码中链接到这样的问题,以防有人阅读并去他为什么这样做?)但是由于我自己的习惯用法,我会在这些界面中使用boost::optional&lt; shared_ptr&lt;T&gt; &gt;空值是可能的/有意义的。这允许类型系统在编译期间参与,以确保需要测试指针是否缺失的任何人都在这样做。它对我很有效,但如果我在不允许可选的上下文中,我将我的例程命名为“funcReturnsSharedPtrMaybeNull”,并且我想提请注意潜在的空值

以上是关于泛化共享指针和 QSharedPointer::data() vs shared_ptr::get()?的主要内容,如果未能解决你的问题,请参考以下文章

C编程中void指针的概念

软件设计师11-面向对象技术

为何训练后的BERT模型不能够很容易的实现模型泛化?

fork(),C 中的共享内存和指针

指针和指针的地址如何共享同一个内存地址? [复制]

共享指针和具有自定义删除器的唯一指针之间的语法差异背后的任何原因