为什么这不是"调用隐式删除的'QQmlElement'的默认构造函数"中的默认构造函数

Why is this not a default constructor in "Call to implicitly-deleted default constructor of 'QQmlElement'

本文关键字:默认 构造函数 QQmlElement 为什么 调用 删除 这不是      更新时间:2023-10-16

我正试图在Qml引擎中注册JB_NodeModel。我得到这个错误:

"对隐式删除的QQmlElement(JB_NodeModel(默认构造函数的调用-由于基类JB_NodeModel没有默认构造函数,因此隐式删除了QQmlElement(JB_Nodel(的默认构造函数。">

但是我看不出默认构造函数有什么问题。如有任何帮助,我们将不胜感激。

我使用了初始化程序列表,但似乎没有帮助。

以下是JB_NodeModel.h:的精简版本

class SP3CORESHARED_EXPORT JB_NodeModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit JB_NodeModel(QObject *parent = nullptr);
~JB_NodeModel();
protected:
JB_Node* rootNode;
JB_Node* actingRootNode;
bool isValidURL(QString fieldName, JB_Node* node) const;
QVector<QString> columnHeadingsV;    
QHash<int, QVector<QString>> mapped_dbFieldNamesH;    
QList<QString> unEditableDBFieldNamesList;
QList<QString> editableCheckBoxDBFieldNamesList; 
private:
JB_DatabaseManager& mDB;
int jobID;
int numOfLevels;
QSharedPointer<JB_NodeModelHelpProt> nodeModelHelper;
QVector<QSharedPointer<QHash<QString, JB_Node*>>> nodesHV;     
QVector<JB_Node*> alteredNodesV;
bool isTreeModel;
bool canEmitDataChanged;
};

以下是JB_NodeModel.cpp构造函数来源:

JB_NodeModel::JB_NodeModel(QObject *parent)
: QAbstractItemModel(parent),
rootNode(nullptr),
actingRootNode(nullptr),
mDB(JB_DatabaseManager::instance()),
jobID(aJobID),
numOfLevels(1),
nodeModelHelper(nullptr),
isTreeModel(true),
canEmitDataChanged(true),
dragDropHelper(false)
{
QSharedPointer<JB_NodeModelHelpProt> aNodeModelHelper(new JB_NodeModHelp_TreeGrpPers());
nodeModelHelper = aNodeModelHelper;
canEmitDataChanged = true;
dragDropHelper = false;
Q_ASSERT(!nodeModelHelper.isNull());
alteredNodesV.clear();
rootNode = nullptr;
actingRootNode = nullptr;

等等。

这里是在QML引擎中注册:

QGuiApplication app(argc, argv);
qmlRegisterType<JB_NodeModel>("JB_NodeModel", 1, 0, "JB_NodeModel");

QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);

这是围绕QQmlElement的qqmlprivate.h的相关部分:

class QJSEngine;
class QQmlEngine;
class QQmlCustomParser;
namespace QQmlPrivate
{
void Q_QML_EXPORT qdeclarativeelement_destructor(QObject *);
template<typename T>
class QQmlElement final : public T
{
public:
~QQmlElement() override {
QQmlPrivate::qdeclarativeelement_destructor(this);
}
static void operator delete(void *ptr) {
// We allocate memory from this class in QQmlType::create
// along with some additional memory.
// So we override the operator delete in order to avoid the
// sized operator delete to be called with a different size than
// the size that was allocated.
::operator delete (ptr);
}
static void operator delete(void *, void *) {
// Deliberately empty placement delete operator.
// Silences MSVC warning C4291: no matching operator delete found
}
};

template<typename T>

//下一行出现错误

void createInto(void *memory) { new (memory) QQmlElement<T>; }
template<typename T>
QObject *createParent(QObject *p) { return new T(p); }

您正在显式定义构造函数。如果您不向构造函数传递任何参数,该怎么办?应该使用哪个构造函数?QAbstractItemModel提供的是带有单个QObject*参数的,还是您定义的带有两个参数的?如果没有任何参数,就不能实例化JB_NodeModel,因为编译器无法决定哪一个构造函数是默认构造函数。换句话说,调用new JB_NodeModel()将是不明确的,因此您的类将没有默认构造函数。

尝试将aJobID设为非默认值,看看它是否有效。如果你必须默认jobID=3:,你也可以像这样创建你的构造函数

explicit JB_NodeModel:JB_NodeModel(QObject *parent = nullptr):
QAbstractItemModel(parent),
jobID(3)
... 
{
...
}

一件非常奇怪的事情是,你是如何成功编译这段代码的?我假设您正在修剪代码以将其包含在这里,但为了让未来的读者清楚:

QAbstractItemModel是一个抽象类,你至少必须实现它的纯虚拟函数

当对QAbstractItemModel进行子类化时,至少必须实现index((、parent((、rowCount((、columnCount((和data((。这些函数用于所有只读模型,并构成基础可编辑模型。

解决了问题。结果发现默认构造函数很好。只是为了尝试一下,我试图在堆栈上创建JB_Node,但得到了一个错误,说构造函数中有int jobid(我已经去掉了(。事实证明,我的.pro文件已经损坏,项目使用的是来自完全不同位置的JB_NodeModel文件(而不是在Qt Creator中打开的文件(-不确定这是怎么发生的,但一旦我修复了项目,一切都很好,在QML Engine中注册的类也可以。现在我无法在TreeView中显示模型数据,所以如果我无法解决问题,我会发布它。感谢回答的人。