链接来自另一个文件的函数时,Qt 上出现错误 LNK 2019 [重复]
Posted
技术标签:
【中文标题】链接来自另一个文件的函数时,Qt 上出现错误 LNK 2019 [重复]【英文标题】:Error LNK 2019 on Qt while linking a function from another file [duplicate] 【发布时间】:2019-06-06 09:35:23 【问题描述】:我在 Windows x86 机器上使用 Qt 版本 4.7.2(我使用旧版本,因为我们的老师将使用这个版本来审查项目)在一个大学项目中工作,但是我在链接某些功能时遇到了一些问题类 Container 到类 QListModelAdapter。
我已经尝试再次运行 qmake,清理并重建项目并删除构建文件夹以从头开始构建它,但没有任何效果,还检查了我的 .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;
容器.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--;
容器.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 文件,所以我现在不包括它,因为已经有很多代码了。
我们将非常感谢您的每一次帮助,非常感谢。
【问题讨论】:
【参考方案1】:模板不是类。只有当给它们一个模板参数时,它们才会被视为实现。话虽如此,在您的 cpp 文件中,方法只是方法模板,它们还不是方法实现。
现在,当您尝试从不同的翻译单元(cpp 文件)调用方法时,链接器将尝试查找方法实现的符号但找不到它,因为编译器不会在cpp 文件,因为它从未使用相应的模板参数在那里调用。
解决方案非常简单:无论谁使用您的模板,都需要有可用的方法模板,这样对方法模板的调用将促使编译器创建所需的实现 -> 将方法实现移动到您的标头文件。您可以完全删除此类模板的 cpp 文件。
编辑:顺便说一句,您在这里创建内存泄漏,因为您在容器类上调用 new
但从不删除。您在这里有两个干净的可能性:由于您使用 Qt,您可以通过让 Container
继承 QObject
来使用它的内存管理。然后,在构造函数中使用列表视图传递给它的父级初始化QObject
。
另一种方法是在QListModelAdapter
中的容器实例周围使用unique_ptr
。 New 仍然有效,您可以通过指针访问该对象。但它会自动清理。
当然,您也可以不使用指针将Container
放入堆栈(只需删除*
并使用.
访问对象)。
请注意,在您自己的析构函数中手动调用 delete
不是现代 C++。它使事情变得更加复杂,您还需要实现复制构造函数和复制赋值运算符。这在 2019 年不再必要或不推荐。 C++ 是一门新鲜的语言,当现在习惯性地使用时,它有多种防止内存泄漏的方法。
我在这里也看到(这开始成为代码审查)是你的命名。 Q
作为宏、函数名、类名等的前缀应该只被Qt
使用。如果有人使用您的代码,否则他们会对您的命名感到困惑。对于这样的用户,很可能您的类名是他们以前没有关注过的实际 Qt 类。
【讨论】:
谢谢!这是我犯的一个愚蠢的错误,非常感谢您提出的所有其他建议,我会尽快修改项目。以上是关于链接来自另一个文件的函数时,Qt 上出现错误 LNK 2019 [重复]的主要内容,如果未能解决你的问题,请参考以下文章