我正在使用Windows x86机器上的Qt 4.7.2版本的大学项目(我使用的是旧版本,因为我们的老师将使用此版本复习该项目),但是在链接某些功能时存在一些问题类Container到类QListModelAdapter。
我已经尝试过再次运行qmake,清理并重建项目,并删除从头开始构建它的build文件夹,但是没有任何作用,还检查了我的.pro文件,但那里似乎没有什么问题。
qlistmodeladapter.h
#ifndef QLISTMODELADAPTER_H
#define QLISTMODELADAPTER_H
#include <QAbstractListModel>
#include "container.h"
class AddLayout;
class QListModelAdapter : public QAbstractListModel {
private:
Container<articolo>* model;
const AddLayout* insert;
public:
QListModelAdapter(QObject* = nullptr, const AddLayout* = nullptr);
~QListModelAdapter() override;
bool insertRows(int, int = 1, const QModelIndex& = QModelIndex()) override;
bool removeRows(int, int = 1, const QModelIndex& = QModelIndex()) override;
};
#endif
qlistmodeladapter.cpp
#include "qlistmodeladapter.h"
#include "container.h"
#include "addlayout.h"
#include <QFont>
QListModelAdapter::QListModelAdapter(QObject* parent, const AddLayout* ins) :
QAbstractListModel(parent),
model(new Container<articolo>()), insert(ins) {}
bool QListModelAdapter::removeRows(int begin, int count, const QModelIndex& parent) {
beginRemoveRows(parent, begin, begin + count - 1);
model->removeEl(begin);
endRemoveRows();
return true;
}
bool QListModelAdapter::insertRows(int begin, int count, const QModelIndex& parent) {
beginInsertRows(parent, begin, begin + count - 1);
articolo art = articolo(new Computer(insert->getNome()));
model->insertEl(art);
endInsertRows();
return true;
}
container.cpp
#include "container.h"
template<class T>
void Container<T>::insertEl(T& p)
{
if (maxSize == size)
{
increaseSize();
}
iteratore it = end();
*(it) = p;
size++;
}
template<class T>
void Container<T>::removeEl(int j)
{
if (j <= size)
{
iteratore it = begin();
for(int i = 0; i <= (j-1); i++)
{
it++;
}
delete it.punt;
iteratore aux = it;
it++;
for(int i = j; i < size-2; i++)
{
aux = it;
aux++;
it++;
}
size--;
}
}
container.h
#ifndef CONTAINER_H
#define CONTAINER_H
#include "items.h"
template<class T>
class Container
{
friend class iteratore;
private:
T* vector;
int size;
int maxSize;
public:
class iteratore {
// is defined correctly
};
Container(T* p = nullptr, int s = 0);//it is defined but not included
void removeEl(int);
void insertEl(T&);
};
#endif // CONTAINER_H
内接函数为removeEl,在哪里出现此错误:
qlistmodeladapter.obj:-1: error: LNK2019: riferimento al simbolo esterno "public: void __cdecl Container<class articolo>::removeEl(int)" (?removeEl@?$Container@Varticolo@@@@QEAAXH@Z) non risolto nella funzione "public: virtual bool __cdecl QListModelAdapter::removeRows(int,int,class QModelIndex const &)" (?removeRows@QListModelAdapter@@UEAA_NHHAEBVQModelIndex@@@Z)
对不起,但是语言是意大利语,奇怪的是,它可以与insertEl一起正常工作,所以我不知道该怎么想。
我已经检查过.pro文件,所以由于现在已经有很多代码,所以我现在不包括它。
我们将非常感谢所有帮助,非常感谢。
答案 0 :(得分:0)
模板不是类。仅当将模板参数提供给它们时,它们才会被视为实现。话虽这么说,在您的cpp文件中,方法只是方法模板,还不是方法实现(尚未)。
现在,当您尝试从其他翻译单元(cpp文件)调用该方法时,链接器将尝试查找方法实现的符号,但找不到它,因为编译器将不会在其中创建相应的符号。 cpp文件,因为从未使用相应的模板参数调用该文件。
解决方案非常简单:无论使用模板的人都需要有可用的方法模板,以便对方法模板的调用将促使编译器创建此所需的实现->将方法实现移至标头文件。您可以完全删除此类模板的cpp文件。
编辑:顺便说一句,您在此处创建了内存泄漏,因为您在容器类上调用了new
但从未删除。这里有两种可能的解决方法:由于您使用Qt,因此可以通过让Container
继承QObject
来使用它的内存管理。然后,在构造函数中,使用您通过列表视图传递给它的父级初始化QObject
。
另一种方法是在unique_ptr
中的容器实例周围使用QListModelAdapter
。 New仍然可以使用,您可以通过指针访问该对象。但是它将自动清除。
当然,您也可以将Container
放在没有指针的堆栈上(只需删除*
并使用.
访问对象)。
请注意,在您自己的析构函数中手动调用delete
并不是现代的C ++。这使事情变得更加复杂,您还需要实现复制构造函数和复制赋值运算符。在2019年不再需要或不建议这样做。 C ++是一种新鲜的语言,当惯用时,它具有多种防止内存泄漏的方法。
我在这里也看到了(这开始成为代码审查)是您的名字。 Q
仅应使用Qt
作为宏,函数名称,类名称等的前缀。如果有人使用您的代码,否则您的命名将使他们感到困惑。对于这样的用户,很可能您的类名是他们之前没有真正关注过的实际Qt类。