QScopedPointers的QList

时间:2016-01-13 08:06:42

标签: qt containers qt5 smart-pointers qscopedpointer

我试图将QScopedPointers存储在QList中。

我发现了这条评论

  

还可以使用QList>。 - Kuba Ober 1月14日&14; 14日18:17

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

和这篇帖子https://forum.qt.io/topic/59338/solved-qlist-of-qscopedpointers暗示这应该有效。但是如果我尝试编译第二个链接的代码,我就会收到这个错误:

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
    ]

为什么这不适合我?

1 个答案:

答案 0 :(得分:8)

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

QScopedPointer禁用了复制构造函数和赋值运算符。您不能为彼此分配两个指针,但您可以使用QScopedPointer::resetQScopedPointer::swapQScopedPointer::take显式转移基础原始指针的所有权。

At some point移动构造函数和移动赋值运算符已添加到QScopedPointer。新的移动语义使这成为可能:

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

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

Later他们还原了这一变化:

  

向QScopedPointer添加移动构造器毫无意义,因为   移动意味着“逃避范围”,这打破了基本点   QScopedPointer。

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

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