泛化共享指针和 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,它建立在QSharedDataPointer
和QSharedData
这样的长期抽象之上。所以当我需要一个普通的共享指针时,为了保持一致性,使用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<>
,但随后注意到可以有效地实现相同的事情(在包含的指针不为空的情况下,我可以通过布尔强制测试是否为空) :
&(*ptr)
如果您正在阅读代码,这会有点慢,并且有人可能会尝试优化(然后很快就会发现这是行不通的)。但除了 WTF 因素之外,它似乎无害……是吗?
【问题讨论】:
学究式地,&*ptr
在指针为空时给出未定义的行为。
@MikeSeymour 是的。但是就像我说的那样,如果需要,您可以 static_cast<bool>
QSharedPointer 和 shared_ptr 来测试 null;他们对此有相同的支持。
【参考方案1】:
我也在我的一个项目中使用它,除了您已经注意到的可读性之外,使用它没有任何问题。正如 Mike Seymour 所指出的,您应该始终首先检查 ptr 不是空指针。
我在大多数情况下使用以下成语:
if( shared_ptr_type ptr = funcReturnsSharedPtr() )
funcAcceptsRawPtr(&*ptr);
几乎可以保证,无论您为shared_ptr_type
使用哪种共享指针类型,它都能正确编译和运行,因为任何合理的共享指针类都会重载operator*
。
【讨论】:
+1 很高兴看到我不是唯一一个。 (我喜欢在代码中链接到这样的问题,以防有人阅读并去他为什么这样做?)但是由于我自己的习惯用法,我会在这些界面中使用boost::optional< shared_ptr<T> >
空值是可能的/有意义的。这允许类型系统在编译期间参与,以确保需要测试指针是否缺失的任何人都在这样做。它对我很有效,但如果我在不允许可选的上下文中,我将我的例程命名为“funcReturnsSharedPtrMaybeNull”,并且我想提请注意潜在的空值以上是关于泛化共享指针和 QSharedPointer::data() vs shared_ptr::get()?的主要内容,如果未能解决你的问题,请参考以下文章