C++ 为什么';t QList是否有resize()方法?
我刚刚注意到C++ 为什么';t QList是否有resize()方法?,c++,qt,qlist,C++,Qt,Qlist,我刚刚注意到QList没有resize方法,而QVector有一个方法。为什么会这样?还有一个等价的函数吗?好吧,这是更一般的答案,但我希望通过比较QList和QVector可以看出为什么不需要手动扩展容器 QList使用内部缓冲区保存指向元素的指针(或者,如果元素小于指针大小,或者元素本身是-元素之一),并且实际数据将保留在堆上 在此期间,删除数据不会减少内部缓冲区(空空间将通过向左或向右移动元素来填充,在开始和结束处留出空间供以后插入) 附加项,如QVector,将在数组的末尾创建额外的新空
QList
没有resize
方法,而QVector
有一个方法。为什么会这样?还有一个等价的函数吗?好吧,这是更一般的答案,但我希望通过比较QList
和QVector
可以看出为什么不需要手动扩展容器
QList使用内部缓冲区保存指向元素的指针(或者,如果元素小于指针大小,或者元素本身是-元素之一),并且实际数据将保留在堆上
在此期间,删除数据不会减少内部缓冲区(空空间将通过向左或向右移动元素来填充,在开始和结束处留出空间供以后插入)
附加项,如QVector
,将在数组的末尾创建额外的新空间,并且由于与QVector
不同,真实数据不存储在内部缓冲区中,所以无论项的大小如何,您都可以在单个指令中创建大量的空间(与QVector
不同)-因为您只是将指针添加到索引缓冲区中
例如,如果您使用32位系统(每个指针4个字节),并且在QList
中存储50个项目,并且每个项目都有1MB大,QVector
缓冲区需要调整为50MB,而QList
的内部缓冲区只需要分配200B内存。这是您需要在QVector
中调用resize()
的地方,但是在QList
中没有必要调用,因为分配小内存块与分配50MB内存一样没有问题
然而,这是有代价的,这意味着您有时需要预先输入QVector
而不是QList
:对于存储在QList
中的单个项,您需要在堆上添加一个alloc,以保留项的真实数据(内部缓冲区中指针指向的数据)。如果您想添加比指针大10000个项目(因为,如果它可以放入指针,它将直接存储在内部缓冲区中),则需要10000个系统调用来为堆上的10000个项目分配数据。但是,如果您使用QVector
,并调用resize
,则可以在单个alloc调用中容纳所有项目-因此,如果您需要大量插入或追加,请不要使用QList
,最好使用QVector
。当然,如果您使用QList
存储共享类,则不需要额外分配,这同样使QList
更合适
因此,对于大多数情况,请选择QList
:
QLinkedList
QVector
数据要快QVector
:
最后,请注意:
QList
(和QVector
)具有reserve(intalloc)
功能,如果alloc
大于内部缓冲区的当前大小,则会导致QList
的内部缓冲区增长。但是,这不会影响QList
的外部大小(size()
将始终返回列表中包含的元素的确切数量)。我认为原因是QList
不要求元素类型具有默认构造函数。
因此,在QList
创建对象时,不存在任何操作,而只复制对象
但是,如果您确实需要调整QList
(无论出于何种原因),这里有一个函数可以做到这一点。请注意,它只是一个方便的函数,编写时并没有考虑性能
模板
void resizeList(QList&list,int newSize){
int diff=newSize-list.size();
T;
如果(差异>0){
列表.储备(差异);
while(diff--)list.append(t);
}else如果(diff<0)list.erase(list.end()+diff,list.end());
}
只要使用
QList<Smth> myList;
// ... some operations on the list here
myList << QVector<Smth>(desiredNewSize - myList.size()).toList();
--这是面向STL的人的:)
有关有效的QList::resize()
可能会有多复杂的背景信息,请参阅:
- ,及
- wasle答案很好,但它会多次添加同一对象。下面是一个实用函数,它将为智能指针列表添加不同的对象
template<class T>
void resizeSmartList(QList<QSharedPointer<T> > & list, int newSize) {
int diff = newSize - list.size();
if (diff > 0) {
list.reserve(diff);
while (diff>0){
QSharedPointer<T> t = QSharedPointer<T>(new T);
list.append(t);
diff--;
}
}else if (diff < 0) list.erase(list.end() + diff, list.end());
}
模板
void resizeSmartList(QList&list,int newSize){
int diff=newSize-list.size();
如果(差异>0){
列表.储备(差异);
而(差异>0){
QSharedPointer t=QSharedPointer(新t);
列表。追加(t);
差异--;
}
}else如果(diff<0)list.erase(list.end()+diff,list.end());
}
如果不使用智能指针,下面将向列表中添加不同的对象
template<class T>
void resizeList(QList<T> & list, int newSize) {
int diff = newSize - list.size();
if (diff > 0) {
list.reserve(diff);
while (diff>0){
T t = new T;
list.append(t);
diff--;
}
}else if (diff < 0) list.erase(list.end() + diff, list.end());
}
模板
void resizeList(QList&list,int newSize){
int diff=newSize-list.size();
如果(差异>0){
列表.储备(差异);
而(差异>0){
template<class T>
void resizeSmartList(QList<QSharedPointer<T> > & list, int newSize) {
int diff = newSize - list.size();
if (diff > 0) {
list.reserve(diff);
while (diff>0){
QSharedPointer<T> t = QSharedPointer<T>(new T);
list.append(t);
diff--;
}
}else if (diff < 0) list.erase(list.end() + diff, list.end());
}
template<class T>
void resizeList(QList<T> & list, int newSize) {
int diff = newSize - list.size();
if (diff > 0) {
list.reserve(diff);
while (diff>0){
T t = new T;
list.append(t);
diff--;
}
}else if (diff < 0) list.erase(list.end() + diff, list.end());
}