我应该使用QScopedPointer还是std

我应该使用QScopedPointer还是std

本文介绍了我应该使用QScopedPointer还是std :: unique_ptr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm starting a new project, using Qt5 and QMAKE_CXXFLAGS += -std=c++1y. I'm not sure whether I should prefer QScopedPointer or std::unique_ptr.

我读了 QScopedPointer 不再那么酷了。

I read somewhere that QScopedPointer is not that cool any more.

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

Does QScopedPointer have any features unique_ptr lacks? Are there any features of unique_ptr that I wouldn't want in when replacing QScopedPointer? Or vice versa?

推荐答案

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

QScopedPointer is strictly weaker than unique_ptr as it does not support move semantics.

其功能在其他方面极为相似。

Its functionality is otherwise extremely similar.

移动语义非常有用,而偶然不正确地使用它们引起问题的情况极为罕见。因此,它们的变化从无害到(通常)有用。

Move semantics are extremely useful, and accidentally using them incorrectly to cause problems is extremely rare. So they vary from harmless to (more typically) helpful.

关于您应该使用 QScopedPointer 的唯一原因是互操作性现有的代码库;

About the only reason you should use QScopedPointer is interoperability with existing code bases; and even there, given how similar they are, an adapter would be pretty easy.

因此,如果它们是如此相似,那么适配器将非常容易。因此,如果不需要调整,请使用 unique_ptr

So if you don't need to adapt, use unique_ptr.

我现在将讨论适应。

棘手的部分是 QScopedPointer 的第二个参数。它非常近似地对应于 unique_ptr 的第二个参数。

The tricky part is the 2nd parameter to QScopedPointer. It very roughly corresponds to the 2nd parameter of unique_ptr.

unique_ptr 有状态的删除器是允许的。在 QScopedPointer 中,它们不是。

In unique_ptr stateful deleters are permitted. In QScopedPointer they are not. The

static void cleanup(T* pointer)

对应于

void operator()(T* pointer)const

unique_ptr 中很漂亮一个基础。因此:

in the unique_ptr in a pretty one-to-one basis. So:

template<class QDelete>
struct std_deleter {
  template<class T>
  void operator()(T* target) const {
    QDelete::cleanup(target);
  }
};

将Qt删除器映射到标准删除器。另一种方式是由删除器无状态限制的。

maps a Qt deleter to a std deleter. The other way is limited by the deleter being stateless:

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 ,反之

which covers about the only reason why you'd use QScopedPointer. There are a few corner cases -- the default deleter QScopedPointer should be converted to a default std::unique_ptr and vice versa.

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

The array delete QScopedPointer should be converted to a unique_ptr<T[]> and vice versa.

在其他情况下,我只是包装了删除程序。从理论上讲,一个真正的花哨的技巧是注意到传入的删除程序是否已经包装好并反转了包装,但是如果您的代码进行了多次往返,则可能已经出了问题。

In other cases, I simply wrap up the deleter. In theory, a really fancy trick would be to notice if the incoming deleter was already wrapped up and reverse the wrapping, but if your code is doing that many round-trips there is probably already something wrong.

这篇关于我应该使用QScopedPointer还是std :: unique_ptr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:52