QScopedPointers的QList

问题描述:

我正尝试将QScopedPointers存储在QList中。

I'm trying to store QScopedPointers in a QList.

我找到了此评论


一个人也可以使用QList>。 – Kuba Ober 2014年1月14日在18:17

One can also use QList >. – Kuba Ober Jan 14 '14 at 18:17

(此答案的第一条评论:https://stackoverflow.com/a/21120575/3095014

(first comment on this answer: https://stackoverflow.com/a/21120575/3095014)

和此帖子 https://forum.qt.io/topic/59338/solved-qlist-of -qscopedpointers 表示这应该起作用。但是,如果我尝试编译第二个链接的代码,则会出现以下错误:

and this post https://forum.qt.io/topic/59338/solved-qlist-of-qscopedpointers which implies that this should work. But if I try to compile the code of the second link, I'm getting this errors:

E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(404) : error C2248: 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer' : cannot access private member declared in class 'QScopedPointer<Label,QScopedPointerDeleter<T>>'
    with
    [
        T=Label
    ]
    E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qscopedpointer.h(170) : see declaration of 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer'
    with
    [
        T=Label
    ]
    E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(403) : while compiling class template member function 'void QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::node_construct(QList<QScopedPointer<T,QScopedPointerDeleter<T>>>::Node *,const QScopedPointer<T,QScopedPointerDeleter<T>> &)'
    with
    [
        T=Label
    ]
    E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(553) : see reference to function template instantiation 'void QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::node_construct(QList<QScopedPointer<T,QScopedPointerDeleter<T>>>::Node *,const QScopedPointer<T,QScopedPointerDeleter<T>> &)' being compiled
    with
    [
        T=Label
    ]
    E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(794) : while compiling class template member function 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::~QList(void)'
    with
    [
        T=Label
    ]
    ..\tableview_row_dnd\main.cpp(13) : see reference to function template instantiation 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::~QList(void)' being compiled
    with
    [
        T=Label
    ]
    ..\tableview_row_dnd\main.cpp(20) : see reference to class template instantiation 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>' being compiled
    with
    [
        T=Label
    ]
E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(405) : error C2248: 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer' : cannot access private member declared in class 'QScopedPointer<Label,QScopedPointerDeleter<T>>'
    with
    [
        T=Label
    ]
    E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qscopedpointer.h(170) : see declaration of 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer'
    with
    [
        T=Label
    ]

为什么这对我不起作用?

Why isn't this working for me?

存储在Qt容器中的值应为assignab数据类型。这意味着他们应该有一个默认的构造函数,一个复制构造函数和一个赋值运算符。

Values stored in Qt containers should be of assignable data types. That means they should have a default constructor, a copy constructor, and an assignment operator.

QScopedPointer 禁用了其复制构造函数和赋值运算符。您不能互相分配两个指针,但是可以使用 QScopedPointer :: reset QScopedPointer显式传输基础原始指针的所有权: :swap QScopedPointer :: take

QScopedPointer has its copy constructor and assignment operator disabled. You can't assign two pointers to each other, but you can explicitly transfer the ownership of the underlying raw pointer using QScopedPointer::reset, QScopedPointer::swap or QScopedPointer::take.

在某个时刻将移动构造函数和移动赋值运算符添加到 QScopedPointer 。新的移动语义使这成为可能:

At some point a move constructor and a move assignment operator were added to QScopedPointer. New move semantics made this possible:

QList<QScopedPointer<Label>> mLabels;
mLabels.append(QScopedPointer<Label>(new Label));

此处将一个临时值添加到列表中,并使用move构造函数创建新的列表项。

Here a temporary value is added to a list and the new list item is created using the move constructor.

稍后他们恢复了该更改:


在QScopedPointer中添加移动构造器是没有意义的,因为
移动意味着逃避了范围,

Adding a move contructor to QScopedPointer makes no sense, because moving means 'escaping the scope', which breaks the fundamental point of QScopedPointer.

如果您真的想拥有一个智能指针列表,则可以使用 QSharedPointer 是可分配的,或者 std :: unique_ptr 支持移动语义。

If you really want to have a list of smart pointers, you can use QSharedPointer which is assignable or std::unique_ptr which supports move semantics.

如果您谈论跟踪 QObjects 子类(尤其是小部件)的生命周期,我建议使用Qt父代机制而不是智能指针。

And if you talk about tracking lifetime of QObjects subclasses and especially widgets, I would suggest to use Qt child-parent mechanism rather than smart pointers.