0
votes

I want to store QPoint in an object, which should be released automatically.

#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();
}

The error message is:

F:\Qt\Qt5.5.0\Tools\mingw492_32\i686-w64-mingw32\include\c++\ext\new_allocator.h:120: error: use of deleted function '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)...); } ^

Does it mean that I am not supposed to use unique_ptr to store QPoint?

2
QPoint is a tiny object, using any pointer and heap allocation is entirely pointless.dtech
You want _points.push_back(std::make_unique<QPoint>(point));.Kerrek SB
AFAIK, it's a generally bad practice to store in vector something you can't properly copy. The answer about it is right, just wanted to add that redesign may also be required.MasterAler
I need a vector which will not remove any element. It seems that storing plain 'QPoint' in a vector and using const reference to assess it is better, right? @MasterAlerZen
I would say 'yes', definitely. QPoint isn't that heavy, unless you have thousands of them, but container will not be your only problem then. Actually, boost::ptr_vector correctly propagates constness, but it would be an awful overkill here. So, yeah, const reference, imho. @ZenMasterAler

2 Answers

7
votes

No, the problem is that you can't push_back a copy of a unique_ptr.

Use push_back(std::move(ptr)) or emplacement construction.

Apart from this, I don't see the need to dynamically allocate a value class such as QPoint.

3
votes

On 64 bit platforms, sizeof(QPoint*) == sizeof(QPoint): the pointer has the same size as the pointed-to-object in the case of QPoint. Moving around the pointers in a vector is no faster than moving around the point values. You're prematurely pessimizing by dynamically allocating these small things one-by-one.

Even on a 32 bit system, the overhead of dynamic allocation will have the performance suffer unnecessarily.

Use a QVector<QPoint> or std::vector<QPoint>, they'll all perform well with points.

TL;DR: Understand the data types that you use, especially if they are simple tuples of integers as QPoint is.