我应该使用QScopedPointer还是std::unique_ptr ?
Should I use QScopedPointer or std::unique_ptr?
我正在开始一个新项目,使用Qt5和QMAKE_CXXFLAGS += -std=c++1y
。我不确定我应该喜欢QScopedPointer
还是std::unique_ptr
。
我在某处读到QScopedPointer
不再那么酷了。
QScopedPointer
有unique_ptr
没有的特性吗?在替换QScopedPointer
时,unique_ptr
是否有任何我不想要的功能?反之亦然?
QScopedPointer
严格弱于unique_ptr
,因为它不支持move语义。
其功能在其他方面极其相似。
Move语义非常有用,不正确地使用它们导致问题的情况非常罕见。所以它们从无害到(更典型的)有帮助。
你应该使用QScopedPointer
的唯一原因是与现有代码库的互操作性;即使在那里,考虑到它们是多么相似,适配器也很容易。
所以,如果你不需要适应,使用unique_ptr
。
我现在将讨论适应。
棘手的部分是QScopedPointer
的第二个参数。它与unique_ptr
的第二个参数非常近似。
在unique_ptr
中允许有状态删除。在QScopedPointer
中,它们不是。
static void cleanup(T* pointer)
对应
void operator()(T* pointer)const
在unique_ptr
中以非常一对一的基础。所以:
template<class QDelete>
struct std_deleter {
template<class T>
void operator()(T* target) const {
QDelete::cleanup(target);
}
};
将Qt删除器映射到std删除器。另一种方式受限于删除器是无状态的:
template<class Std_deleter>
struct Qt_deleter {
template<class T>
static void cleanup(T* target) {
static_assert(std::is_empty<Std_deleter>{}, "Only works with stateless deleters");
Std_deleter{}(target);
}
};
现在可以转换为:
template<class T, class D>
QScopedPointer<T, Qt_deleter<D>>
to_qt( std::unique_ptr<T, D>&& src ) {
return src.release();
}
template<class T, class D>
QScopedPointer<T, Qt_deleter<D>>
to_qt( std::unique_ptr<T[], D>&& src ) {
return src.release();
}
template<class T>
QScopedPointer<T>
to_qt( std::unique_ptr<T>&& src ) {
return src.release();
}
template<class T>
QScopedPointer<T, QScopedPointerArrayDeleter>
to_qt( std::unique_ptr<T[]>&& src ) {
return src.release();
}
template<
class T, class D, class R=std::unique_ptr<T, std_deleter<D> >
>
to_std( QScopedPointer<T, D>&& src ) {
return R(src.take()); // must be explicit
}
template<class T, class R=std::unique_ptr<T>>
to_std( QScopedPointer<T>&& src ) {
return R(src.take()); // must be explicit
}
template<class T, class R=std::unique_ptr<T[]>>
to_std( QScopedPointer<T,QScopedPointerArrayDeleter >&& src ) {
return R(src.take()); // must be explicit
}
包含了使用QScopedPointer
的唯一原因。有一些极端的情况——默认的删除器QScopedPointer
应该转换为默认的std::unique_ptr
,反之亦然。
数组delete QScopedPointer
应转换为unique_ptr<T[]>
,反之亦然。
在其他情况下,我只是将删除器包装起来。理论上,一个真正奇特的技巧是注意到传入的删除器是否已经被包装并反转包装,但是如果您的代码进行了那么多次往返,那么可能已经有问题了。
与标准库中的东西相比,为什么要使用非标准库中的东西呢?
对我来说,任何优秀的程序员会这么做的原因只有一个:如果外部库提供了标准库没有提供的东西。是这样吗?
考虑你的程序的可移植性和将来的更新,然后再做决定。
尽管这两个类的主要目的是相似的,但它们之间的一个重要区别会使您做出一些业务决策。
QScopedPointer没有赋值操作符。其中std::unique_ptr具有赋值操作符
如果你想严格控制你的QT对象/控制,不希望分配使用QScopedPointer。
- 为什么 std::unique 不调用 std::sort?
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 生成"unique"矩阵
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 我对 std::unique(算法)C++有问题
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- std::shared_ptr::unique(),复制和线程安全
- 如何在C++03中用自定义谓词调用std::unique
- C++中的指针否定 (!ptr == NULL)
- C++14 unique_ptr并使用已删除的函数'std::unique-ptr' unique_ptr错误