首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该使用QScopedPointer还是std::unique_ptr?

我应该使用QScopedPointer还是std::unique_ptr?
EN

Stack Overflow用户
提问于 2016-10-31 16:27:32
回答 3查看 9.3K关注 0票数 14

我正在使用Qt5和QMAKE_CXXFLAGS += -std=c++1y启动一个新项目。我不确定我应该选择QScopedPointer还是std::unique_ptr

我读过somewhereQScopedPointer不再那么酷了。

QScopedPointer是否有unique_ptr所缺乏的特性?在替换unique_ptr时,是否有我不想使用的QScopedPointer特性?反之亦然?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-31 17:06:31

QScopedPointerunique_ptr更弱,因为它不支持移动语义。

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

移动语义是非常有用的,不小心不正确地使用它们来引发问题是非常罕见的。因此,它们从无害到(更典型的)有帮助。

您应该使用QScopedPointer的唯一原因是与现有代码库的互操作性;即使在那里,考虑到它们有多么相似,适配器也会非常容易。

因此,如果您不需要适应,请使用unique_ptr

我现在将讨论适应。

棘手的部分是QScopedPointer的第二个参数。它大致相当于unique_ptr的第二个参数。

unique_ptr中,允许有状态删除。在QScopedPointer,他们不是。这个

代码语言:javascript
复制
static void cleanup(T* pointer)

对应于

代码语言:javascript
复制
void operator()(T* pointer)const

unique_ptr的基础上是一对一的。所以:

代码语言:javascript
复制
template<class QDelete>
struct std_deleter {
  template<class T>
  void operator()(T* target) const {
    QDelete::cleanup(target);
  }
};

将Qt删除器映射到std删除器。另一种方式由于删除者是无国籍人而受到限制:

代码语言:javascript
复制
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);
  }
};

我们现在可以转换:

代码语言:javascript
复制
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[]>,反之亦然。

在其他情况下,我只是简单地结束删除。理论上,一个非常奇妙的技巧是注意到传入删除器是否已经被包装并反转包装,但是如果您的代码正在执行那么多的往返旅行,那么可能已经有问题了。

票数 20
EN

Stack Overflow用户

发布于 2016-10-31 16:56:22

为什么要使用标准库中的东西而不是标准库中的东西?

对我来说,任何优秀的程序员都会这么做,只有一个原因:如果外部库提供了标准库没有提供的东西。是这样吗?

考虑您的程序的可移植性和将来的更新,然后作出决定。

票数 4
EN

Stack Overflow用户

发布于 2016-10-31 16:39:34

尽管这两个类的主要意图是相似的,但这两个类之间的一个重要区别使您可以做出一些业务决策。

QScopedPointer没有赋值运算符。其中std::unique_ptr有赋值运算符.

如果您希望严格执行QT对象/控件,并且不希望进行赋值,请使用QScopedPointer。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40346393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档