【问题标题】:Doesn't `QPoint` support `std::unique_ptr`?`QPoint` 不支持 `std::unique_ptr` 吗?
【发布时间】:2016-03-05 19:17:23
【问题描述】:

我想将QPoint 存储在一个应该自动释放的对象中。

#include <QCoreApplication>
#include <memory>
#include <QPoint>

using namespace std;
class MyWidget{
public:
    vector<std::unique_ptr<QPoint>> _points;
    void f(QPoint point){
        std::unique_ptr<QPoint> pos(new QPoint(point));
        _points.push_back(pos);
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    MyWidget wid;
    wid.f(QPoint(0,0));

    return a.exec();
}

错误信息是:

F:\Qt\Qt5.5.0\Tools\mingw492_32\i686-w64-mingw32\include\c++\ext\new_allocator.h:120: 错误:使用已删除的函数 'std::unique_ptr<_tp _dp>::unique_ptr(const std::unique_ptr<_tp _dp>&) [with _Tp = QPoint; _Dp = std::default_delete]' { ::new((void *)__p) _Up(std::forward<_args>(__args)...); } ^

这是否意味着我不应该使用unique_ptr 来存储QPoint

【问题讨论】:

  • QPoint 是一个小对象,使用任何指针和堆分配完全没有意义。
  • 你想要_points.push_back(std::make_unique&lt;QPoint&gt;(point));
  • AFAIK,将无法正确复制的内容存储在矢量中通常是一种不好的做法。关于它的答案是正确的,只是想补充一点,可能还需要重新设计。
  • 我需要一个不会删除任何元素的向量。似乎将普通的“QPoint”存储在向量中并使用 const 引用来评估它会更好,对吧? @MasterAler
  • 我肯定会说“是”。 QPoint 没有那么重,除非你有成千上万个,但容器不会是你唯一的问题。实际上,boost::ptr_vector 正确地传播了 constness,但在这里这将是一个可怕的矫枉过正。所以,是的,常量参考,恕我直言。 @禅

标签: qt c++11


【解决方案1】:

不,问题是你不能push_back 一个unique_ptr副本

使用push_back(std::move(ptr))emplacement 构造。

除此之外,我认为不需要动态分配值类,例如QPoint

【讨论】:

    【解决方案2】:

    在 64 位平台上,sizeof(QPoint*) == sizeof(QPoint):在QPoint 的情况下,指针与指向对象的大小相同。围绕向量中的指针移动并不比围绕点值移动快。通过一一地动态分配这些小东西,您过早地感到悲观。

    即使在 32 位系统上,动态分配的开销也会对性能造成不必要的影响。

    使用QVector&lt;QPoint&gt;std::vector&lt;QPoint&gt;,它们都会在得分方面表现出色。

    TL;DR:了解您使用的数据类型,尤其是当它们是像 QPoint 这样的简单整数元组时。

    【讨论】:

    • 不要使用QList&lt;QPoint&gt;,在 32 位系统上这将是一场灾难!
    • @peppe 没错。完全没有理由使用它,真的,所以我已经删除了它。感谢您指出这一点。
    猜你喜欢
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 2014-05-12
    相关资源
    最近更新 更多