C++ 覆盖虚方法抛出错误“LNK2001: unresolved external symbol”

Posted

技术标签:

【中文标题】C++ 覆盖虚方法抛出错误“LNK2001: unresolved external symbol”【英文标题】:C++ override virtual method throws an error "LNK2001: unresolved external symbol" 【发布时间】:2014-04-06 17:41:05 【问题描述】:

我正在开发 C++ Qt 应用程序。我有一个抽象班和两个孩子。其中一个孩子完全按照应有的方式工作,但第二个却导致错误:

Freewer.obj:-1: 错误: LNK2001: 无法解析的外部符号“public: virtual void __thiscall Sierpinski::render(class QPainter &,class QRect)” (?render@Sierpinski@@UAEXAAVQPainter@@VQRect@@@ Z)

找不到文件:Freewer.obj

问题是,两个孩子的定义方式相同。 让我们向您展示我的代码。

分形.h:

#ifndef FRACTAL_H
#define FRACTAL_H

#include <QPainter>
#include <QRect>
#include <QDebug>

class Fractal

public:
    virtual void render(QPainter &painter, QRect target) = 0;
;

#endif // FRACTAL_H

Cantor.h:

#ifndef CANTOR_H
#define CANTOR_H

#include "Fractal.h"

class Cantor : public Fractal

public:
    void render(QPainter &painter, QRect target) Q_DECL_OVERRIDE;
;

#endif // CANTOR_H

Cantor.cpp:

#include "Cantor.h"

void Cantor::render(QPainter &painter, QRect target)

    Q_UNUSED(painter);
    Q_UNUSED(target);

    qDebug() << "Rendering Cantor's Discontinuum...";

谢尔宾斯基.h:

#ifndef SIERPINSKI_H
#define SIERPINSKI_H

#include "Fractal.h"

class Sierpinski : public Fractal

public:
    void render(QPainter &painter, QRect target) Q_DECL_OVERRIDE;
;

#endif // SIERPINSKI_H

谢尔宾斯基.cpp:

#include "Sierpinski.h"

void Sierpinski::render(QPainter &painter, QRect target)

    Q_UNUSED(painter);
    Q_UNUSED(target);

    qDebug() << "Rendering Sierpinski triangle...";

现在,当我想创建 Cantor 类的实例时,它可以正常工作。但是当我想创建一个 Sierpinski 类的实例时,它会导致我上面写的错误。

当我以这种方式更改 Sierpinsky 头文件时:

谢尔宾斯基.h:

#ifndef SIERPINSKI_H
#define SIERPINSKI_H

#include "Fractal.h"

class Sierpinski : public Fractal

public:
    void render(QPainter &painter, QRect target)
    
        Q_UNUSED(painter);
        Q_UNUSED(target);

        qDebug() << "Rendering Sierpinski triangle...";
    
;

#endif // SIERPINSKI_H

我不会使用 Sierpinski.cpp,一切正常。是不是很奇怪?你能帮我吗?我哪里有什么错误?我想以与康托尔相同的方式使用谢尔宾斯基定义。

非常感谢。

编辑:

@Joachim Isaksson 的问题之后,我尝试以与 Cantor 和 Sierpinski 相同的方式添加另一个分形,但我遇到了与 Sierpinski 相同的错误。新课程称为 Koch,但它不起作用。但是当我离开 Koch.cpp 文件并直接在头文件中使用渲染函数的定义时,一切正常。

【问题讨论】:

看起来好像没有链接 Sierpinski.cpp/Sierpinski.o。您确定您没有打错名称并且链接器会发出警告吗? 是的,所有文件名和包含都是由 Qt Creator 生成的,我尝试了更多次。未发出警告。 你能把.pro文件的内容贴出来吗,看来Sierpinski.cpp没有添加到中的项目中来源 或者它可能被添加了,但是从那以后您手动更改了文件结构。但是@Zlatomir 肯定是正确的,这是 .pro 文件的问题。还要确保在重建之前清理/运行 qmake,过时的 Makefile(由 qmake 生成)也可以这样做。 @LaszloPapp 它应该自动运行,但它不会自动运行是一个常见问题,因此 Matt Phillips 可能对文件是正确的,并且 run qmake 可以修复错误。 【参考方案1】:

首先,您误用了“儿童”一词。你的意思是子类。在 Qt 世界中,孩子意味着不同的东西。

可能的原因是您的 qmake 项目文件中的SOURCES 变量中没有相应的源文件。

一旦您进行了修改,请确保 qmake 正确地重新运行。

【讨论】:

谢谢,我不知道。我使用“子类”作为 OOP 元素的“子类”。而你,部分@Zlatomir@Matt Phillips 是对的。我的 .pro 文件内容是正确的,但似乎 makefile 是错误的。我会在重建之前手动运行 qmake,现在一切正常。再次感谢你。但是现在,我不知道应该将谁的答案标记为“答案”。 @elefantito:很好,但只有一个答案,我用那个提示更新了我的答案。通常,qmake 应该重新运行,但如果您遵循正确的工作流程,您似乎会遇到错误。我个人什至总是做一个清理,在这种情况下重新运行 qmake 是没有必要的。

以上是关于C++ 覆盖虚方法抛出错误“LNK2001: unresolved external symbol”的主要内容,如果未能解决你的问题,请参考以下文章

C++ 虚函数 (virtual function)

C++ 纯虚函数 虚函数 override

C++:管理虚方法:override和final

C++:动态共享库中的虚函数产生段错误

C++ 中,类的继承:父类当使用虚函数时候,子类对该函数进行重写的话,属于子类成员函数对虚函数的覆盖!

关于C++的虚函数在父类的内部调用