问题描述
我正在尝试将 QScopedPointers 存储在 QList 中.
我找到了这条评论
也可以使用 QList >.– Kuba Ober 2014 年 1 月 14 日 18:17
(对此答案的第一条评论:https://stackoverflow.com/a/21120575/3095014)p>
和这篇文章 https://forum.qt.io/topic/59338/solved-qlist-of-qscopedpointers 这意味着这应该有效.但是,如果我尝试编译第二个链接的代码,则会出现以下错误:
E:QtQt5Enterprise5.5msvc2013includeQtCore/qlist.h(404) : 错误 C2248: 'QScopedPointer>::QScopedPointer"的声明和[T=标签]E:QtQt5Enterprise5.5msvc2013includeQtCore/qlist.h(403) : 在编译类模板成员函数 'void QList>>::node_construct(QList<QScopedPointer<T,QScopedPointerDeleter<T>>>::Node *,const QScopedPointer<T,QScopedPointerDeleter<T>> &)'和[T=标签]E:QtQt5Enterprise5.5msvc2013includeQtCore/qlist.h(553) :参见函数模板实例化的参考 'void QList>>::node_construct(QList<QScopedPointer<T,QScopedPointerDeleter<T>>>::Node *,const QScopedPointer<T,QScopedPointerDeleter<T>> &)' 正在编译和[T=标签]E:QtQt5Enterprise5.5msvc2013includeQtCore/qlist.h(794) : 在编译类模板成员函数'QList
为什么这对我不起作用?
存储在 Qt 容器中的值应该是可分配的数据类型.这意味着它们应该有一个默认构造函数、一个复制构造函数和一个赋值运算符.
QScopedPointer
已禁用其复制构造函数和赋值运算符.您不能将两个指针相互分配,但您可以使用 QScopedPointer::reset
、QScopedPointer::swap
或 显式转移底层原始指针的所有权>QScopedPointer::take
.
在某个时候添加了移动构造函数和移动赋值运算符到 QScopedPointer
.新的移动语义使这成为可能:
QList>标号;mLabels.append(QScopedPointer
这里将一个临时值添加到列表中,并使用移动构造函数创建新的列表项.
后来他们恢复了这个更改:
向 QScopedPointer 添加移动构造函数没有意义,因为移动意味着逃避范围",它打破了基本点的 QScopedPointer.
如果你真的想要一个智能指针列表,你可以使用可赋值的QSharedPointer
或支持移动语义的std::unique_ptr
.
如果您谈论跟踪 QObjects
子类尤其是小部件的生命周期,我建议使用 Qt 子父机制而不是智能指针.
I'm trying to store QScopedPointers in a QList.
I found this comment
(first comment on this answer: https://stackoverflow.com/a/21120575/3095014)
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:QtQt5Enterprise5.5msvc2013includeQtCore/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:QtQt5Enterprise5.5msvc2013includeQtCore/qscopedpointer.h(170) : see declaration of 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer'
with
[
T=Label
]
E:QtQt5Enterprise5.5msvc2013includeQtCore/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:QtQt5Enterprise5.5msvc2013includeQtCore/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:QtQt5Enterprise5.5msvc2013includeQtCore/qlist.h(794) : while compiling class template member function 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::~QList(void)'
with
[
T=Label
]
.. ableview_row_dndmain.cpp(13) : see reference to function template instantiation 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::~QList(void)' being compiled
with
[
T=Label
]
.. ableview_row_dndmain.cpp(20) : see reference to class template instantiation 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>' being compiled
with
[
T=Label
]
E:QtQt5Enterprise5.5msvc2013includeQtCore/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:QtQt5Enterprise5.5msvc2013includeQtCore/qscopedpointer.h(170) : see declaration of 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer'
with
[
T=Label
]
Why isn't this working for me?
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
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
.
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));
Here a temporary value is added to a list and the new list item is created using the move constructor.
Later they reverted that change:
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.
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.
这篇关于QScopedPointers 的 QList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!