链接来自另一个文件的函数时,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 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

liunx ln命令 硬链接和软链接区别

Linux命令----ln

Linux ln 命令

ln&硬链接&软链接

ln用法

Linux命令 在文件或目录之间创建链接 ln