如何初始化QVector

12

我是c++和Qt的新手,我正在尝试像这样在类初始化列表中初始化一个QVector:

MyClass::MyClass(QWidget *parent) : QMainWindow(parent) , myVector(QVector<double>(100))

我本以为 QVector 已经分配了 100 个索引,但是当我尝试读取 myVector[0] 时,出现了一个断言错误,提示 "Unhandled exception at 0x0143bf77 in test.exe: 0xC0000005: Access violation reading location 0x00000004.",程序停在了 Qt 的这一行代码处:

inline T &QVector<T>::operator[](int i)
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
  return data()[i]; }

我相信这表明我正在尝试访问尚未分配的成员,所以我猜我没有正确使用初始化列表。我可以将其制作为指针,并在构造函数中进行new QVector(100),但我想知道问题在哪里以及如何使其正确。


3
在构造函数中,只需使用 myVector(100) 即可。 - coproc
我正在一个for循环中,所以first()不能使用。 - Michel Feinstein
如果我执行 myVector(100),我会得到以下错误:非 const 引用的初始值必须是左值。 - Michel Feinstein
@mFeinstein:显示一下myVector的声明。 - László Papp
3个回答

14

你可能因为没有展示代码而在做错了某些事情,因为下面的代码对我来说可以正常工作,它应该是按设计实现的。请注意,对于第一个元素,您可以使用方便的first方法

main.cpp

#include <QVector>
#include <QDebug>

int main()
{
    QVector<double> myVector(QVector<double>(100));
    qDebug() << "TEST FIRST:" << myVector.first();
    return 0;
}

main.pro

TEMPLATE = app
TARGET = main
SOURCES += main.cpp

输出

TEST FIRST: 0

正如我在评论中所提到的,您可以使用reserve方法

void QVector::reserve(int size)

尝试至少为size个元素分配内存。如果您事先知道向量的大小,可以调用此函数,如果经常调用resize(),则可能会获得更好的性能。如果size是低估的,则最糟糕的情况是QVector会变得稍微慢一些。

此函数的唯一目的是提供微调QVector内存使用的手段。一般来说,您很少需要调用此函数。如果要更改向量的大小,请调用resize()。

那么,您可以编写类似于以下内容的代码:

MyClass::MyClass(QWidget *parent)
    : QMainWindow(parent)
{
    myVector.reserve(100);
}

然而,正如我在评论中稍后指出的那样,简单的构造函数也应该像这样工作:

MyClass::MyClass(QWidget *parent)
    : QMainWindow(parent)
    , myVector(100)
{
}

你正在调用复制构造函数(虽然是为隐式共享类),因此它可能会稍微慢一些。它至少比你需要的代码更多。


我犯了个错误 :P 我忘记在 .h 文件中尝试将它放置为引用,例如 &myVector,因此删除引用后,它可以与我的原始代码一起工作,非常感谢。 - Michel Feinstein
@mFeinstein:很高兴你解决了。请注意这就是我为什么要求声明的原因。 - László Papp
是的,我忘记了再次检查声明。 - Michel Feinstein

3
尝试像这样做:
QVector<double> * vect = new QVector<double>;
vect->reserve(100);

void QVector::reserve(int size)

尝试分配至少size个元素的内存。如果您事先知道向量的大小,可以调用此函数,并且如果经常调用resize(),则可能会获得更好的性能。如果size低估了,最坏的情况是QVector会变慢一些。 此函数的唯一目的是提供微调QVector内存使用的手段。通常,您很少需要调用此函数。如果要更改向量的大小,请调用resize()。

但这只会保留内存,如果您想浏览它,请使用fill(<double>)


正如我在问题中所说,我想学习如何使用初始化列表来完成它,我知道我可以用指针来解决问题...但还是谢谢。 - Michel Feinstein

0
QVector<double> * vect = new QVector<double>;
vect->resize(100);

void QVector::resize(int size) 将向量的大小设置为size。如果size大于当前大小,则在末尾添加元素;新元素使用默认构造值进行初始化。如果size小于当前大小,则从末尾删除元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接