QVector结构体 - 无适当的默认构造函数可用

5

我非常困惑为什么这不起作用。我一定是对QVectors的某个关键点有误解...

我创建了一个MCVE来展示这个问题:

#include <QCoreApplication>
#include <QVector>

struct ChunkRequest
{
    ChunkRequest(int x, int z)
    {
        this->x = x;
        this->z = z;
    }

    int x;
    int z;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QVector<ChunkRequest> requestedChunks;

    requestedChunks.append(ChunkRequest(1, 2));

    return a.exec();
}

编译出错,错误信息为“C2512: 'ChunkRequest' : 没有可用的默认构造函数”。我可以使用“ChunkRequest req(1, 2);”创建一个“ChunkRequest”变量,但是一旦我尝试将其附加到我的“QVector”中,就会抛出错误。对此我感到困惑。
编辑: 阅读您的评论后,我明白了QVector需要一个默认构造函数才能确定数组中每个元素的大小。但这并不能解释为什么。 如果一个结构体有一定数量的成员,并且每个成员在内存中有已知的大小(甚至动态内存的指针也是已知的大小),那么我不明白为什么QVector需要一个默认构造函数?大小应该在编译时就已知……对吗?

1
另请参阅:https://dev59.com/lJDea4cB1Zd3GeqPcoXC - MrEricSir
1
@mrg95 这个问题在文档中有点难找,但是需要一个默认构造函数。每当你在C++中提供一个构造函数时,它会覆盖默认构造函数,这意味着你可能需要提供自己的默认构造函数(即使它是一个空操作)。这只是语言的一种怪癖。 - MrEricSir
这让我震惊,因为我认为大小可以在编译时确定。那我对此有什么误解吗? - mrg95
@mrg95,你说得完全正确,它在编译时是已知的大小。在编译时不知道的是成员变量的默认值,因为像int这样的基本类型没有默认值。如果 QVector 需要分配额外的元素,那么就需要调用默认构造函数来为成员变量提供值,这一点很重要。 - MrEricSir
啊,我明白了。我不知道 QVector 在分配空间时实际上会创建额外的元素。我以为它只是分配了空间...... 谢谢你的帮助 :) 如果你愿意,可以将此作为答案发布,我会接受它。 - mrg95
显示剩余6条评论
2个回答

4
在C++中,为结构体(或类)指定任何构造函数都会告诉编译器不要自动提供默认构造函数。这是语言的一个怪癖。
对于容器类(如QVector),这将成为一个问题,因为它可以在运行时调整大小(内部或显式地)。当分配新对象以填充空间时,它将调用默认构造函数--但如果没有可用的默认构造函数,则会在编译时出现错误。
可以通过指定默认构造函数来解决这个问题,即使它什么也不做,例如:
ChunkRequest() {}

2
很明显,QVector需要一个默认构造函数来确定数组中每个元素的大小。但这并不能回答为什么需要这样做。
实际上,构造函数与对象的大小无关,它们的成员布局才是关键。
强制使用默认构造函数的是QVector的构造函数和方法,它们允许设置大小。该构造函数将用于初始化所有这些元素。
如果没有默认构造函数,这些值将未初始化,几乎没有用处。
拥有默认构造函数告诉你:“我可以构造出该类型的有意义的对象,而不需要传递任何参数。”
无论您个人是否使用这些构造函数或方法,类实现都需要它。
至于为什么它还使用构造函数来处理基本上是保留内存的问题,这可能需要单独提问,因为对我来说根本没有好的理由去这样做,它似乎是潜在的开销。

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