使用QVector时,没有匹配的默认构造函数。

5
我有一个类B,它创建了一个类A的对象并调用了对象的一个方法。
a.h
#ifndef A_H
#define A_H

class A
{
public:
    A(int);
    void function();
};

#endif // A_H

a.cpp

#include "a.h"

A::A(int x)
{

}
void A::function(){
    //Do something.
}

b.h

#ifndef B_H
#define B_H
#include <QVector>
#include <a.h>


class B
{
public:
    B(int);
    QVector<A> list;
};

#endif // B_H

b.cpp

#include "b.h"

B::B(int y)
{
    list.append(A(y));
    list[0].function();
}  

问题在于此无法编译。它返回“没有匹配的函数调用‘A:A()’”。我知道这可以通过前向声明来解决,但在这里不起作用,因为我想调用函数“function”。我也不想在类B中包含整个类A。

2
似乎Qt要求一个默认构造函数。 - TrebledJ
2
“没有可调用的匹配函数'A:A()'”意味着 A 没有默认构造函数,但您正在尝试调用它。 - 463035818_is_not_a_number
2个回答

11
与许多Qt容器一样,您的版本中QVector的元素类型必须是可分配的数据类型
与标准库不同,Qt将其定义为
各种容器中存储的值可以是任何可分配的数据类型。要符合条件,类型必须提供默认构造函数、复制构造函数和赋值运算符。
这真的很不幸,因为在您的示例中没有实际需要默认构造函数, 实际上,一个std::vector会(兼容地)让您使用一个没有默认构造函数的元素类型。 QVector :: value(int)函数确实依赖于此属性,但您未使用它! Qt开发人员必须进行某种预先检查,而不是采用标准库的方法“仅在实际需要时检查前提条件”,否则这是代码的“意外”!
因此,直到5.13才更改了这一点, 很抱歉,您将不得不给A提供一个默认构造函数

不要忘记拷贝构造函数,还需要对A::function()的定义进行适当的限定。

前向声明无法解决这个问题,你也不需要前向声明。实际上,在这个特定的程序中添加前向声明将完全没有任何作用。 ;)


2
另一种解决方案当然是切换到 std::vector - Martin Bonner supports Monica
1
大家好!好消息!QVector 的默认构造函数要求终于在 5.13 版本中被取消了(查看提交记录)。 - peppe
Qt的开发人员必须进行某种前置检查,而不是采用标准库的方法“只在实际需要时检查前提条件”。更糟糕的是...这只是粗心的编码,例如从插入函数中调用resize()之类的东西 :-( - peppe
@peppe:可能。也可能不是。(如果你从源代码中确切知道,请忽略此消息!) - Lightness Races in Orbit
血腥细节:在5.12中,detach()(由任何非const函数调用,例如插入函数)调用reallocData(),这是一个一刀切的函数,执行分离、分配、调整大小、保留等操作。结果是强制要求。其他函数也编写得很松散(例如,在5.12中,clear() 调用 resize(0))。 - peppe

0

首先在 a.cpp 中更新函数定义:

void A::function(){  // A: added
    //Do something.
}

其次,我会添加 A(const A&) 拷贝构造函数,因为列表可能需要此函数进行内部缓冲区重新分配。


2
虽然您说得没错,function定义目前是有问题的,需要添加一个复制构造函数,但这并没有回答问题,问题是为什么会调用默认构造函数以及如何最好地解决它。 - Lightness Races in Orbit

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