gpt4 book ai didi

c++ - 我应该使用 QScopedPointer 还是 std::unique_ptr?

转载 作者:可可西里 更新时间:2023-11-01 17:30:51 27 4
gpt4 key购买 nike

我正在开始一个新项目,使用 Qt5 和 QMAKE_CXXFLAGS += -std=c++1y。我不确定我应该更喜欢 QScopedPointer 还是 std::unique_ptr

我读了somewhere QScopedPointer 不再那么酷了。

QScopedPointer 是否有 unique_ptr 缺少的功能?在替换 QScopedPointer 时,是否有任何我不想使用的 unique_ptr 功能?还是相反?

最佳答案

QScopedPointer严格弱于unique_ptr因为它不支持移动语义。

它的功能在其他方面非常相似。

移动语义非常有用,不小心错误地使用它们而导致问题的情况极为罕见。因此它们从无害到(更典型地)有益。

关于您应该使用 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反之亦然。

数组删除QScopedPointer应转换为 unique_ptr<T[]>反之亦然。

在其他情况下,我只是将删除器包装起来。从理论上讲,一个非常奇特的技巧是注意传入的删除器是否已经包装并反转包装,但如果您的代码进行了那么多次往返,则可能已经有问题了。

关于c++ - 我应该使用 QScopedPointer 还是 std::unique_ptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40346393/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com