c++ - 具有虚函数的未解析外部符号

标签 c++ qt external virtual symbols

我试图通过使用 qt 设计模式中的示例来了解虚函数的行为

这里我有一个头文件,其中定义了 2 个类:

#ifndef ABCLASSES_H
#define ABCLASSES_H
#include <QTextStream>

class A
{
public:
    virtual ~A()
    {

    }
    virtual void foo(QTextStream& out);
    virtual void bar(QTextStream& out);
};

class B: public A
{
public:
    void foo(QTextStream& out);
    void bar(QTextStream& out);
};

#endif // ABCLASSES_H

这是这些类的源文件

#include "abclasses.h"

void A::foo(QTextStream& out)
{
    out << "A's foo" << endl;
    bar(out);
}

void A::bar(QTextStream& out)
{
    out << "A's bar" << endl;
}

void B::foo(QTextStream& out)
{
    out << "B's foo" << endl;
    A::bar(out);
}

void B::bar(QTextStream& out)
{
    out << "B's bar" << endl;
}

问题是我无法根据这些定义创建或使用任何类。我得到的错误是

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl A::foo(class QTextStream &)" (?foo@A@@UEAAXAEAVQTextStream@@@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl A::bar(class QTextStream &)" (?bar@A@@UEAAXAEAVQTextStream@@@Z)

因为我对虚函数了解不多。我认为可能需要重新声明 B 类中的函数,但这也无济于事,并且在我的日志中又添加了 2 个错误。

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl B::foo(class QTextStream &)" (?foo@B@@UEAAXAEAVQTextStream@@@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl B::bar(class QTextStream &)" (?bar@B@@UEAAXAEAVQTextStream@@@Z)

书中的示例只是在声明函数后(在同一文件中)实现函数,这似乎可行。我想知道为什么我的不起作用,是否有解决方法

编辑: 项目文件使用这些设置:

#-------------------------------------------------
#
# Project created by QtCreator 2015-08-23T11:53:16
#
#-------------------------------------------------

QT       += core

QT       -= gui

TARGET = untitled1
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app


SOURCES += main.cpp \
    student.cpp \
    abclasses.cpp

HEADERS += \
    student.h \
    abclasses.h

我不得不说,在构建、链接东西方面我不太了解,但我现在不需要将它们集中在一个小项目上。由于 abclases.cpp 在源代码中,我认为它用于构建过程。

student.h 和 .cpp 与我在同一个项目中进行的另一个试用相关。它们现在没有被积极使用,下面是 main.cpp

#include <QCoreApplication>
#include <QTextStream>
//#include "student.h"
#include "abclasses.h"

//void finish(Student& student)
//{
//    QTextStream cout(stdout);
//    cout << "The following " << student.getClassName()
//         << "has applied for graduation" << endl
//         << student.toString() << endl;
//}

int main() {
    QTextStream cout(stdout);
    B bobj;
//    A *aptr = &bobj;
//    aptr->foo(cout);
//    cout << "-------------" << endl;
//    A aobj = *aptr;
//    aobj.foo(cout);
//    cout << "-------------" << endl;
//    aobj = bobj;
//    aobj.foo(cout);
//    cout << "-------------"<< endl;
//    bobj.foo(cout);
}

编辑 2: 更新了过时的错误消息,更新了 abclasses.h

最佳答案

abclassess.cpp 文件未编译,因为 makefile 与 .pro 文件相比已过时。右键单击 Qt Creator 中最顶层的项目节点,然后选择 Run qmake。然后再次构建项目。

不幸的是,这是在 Windows 上表现出来的 Qt Creator 和 qmake 之间的不良交互。在该平台上,qmake 生成三个 makefile:MakefileMakefile.releaseMakefile.debug。不幸的是,只有顶级 makefile 在 .pro 文件和 makefile 之间具有适当的依赖关系:每当项目文件更改时,make 调用 qmake 将自动重新生成 makefile。通常这不会成为问题,因为当您手动构建时,您会调用顶部 Makefile 上的 nmake/jom

但 Qt Creator 会根据发布/调试构建的需要分别直接调用 Makefile.releaseMakefile.debug。这会绕过仅存在于基础 Makefile 中的 makefile 重新生成规则。正是这种交互是错误/不当行为的根源,(不幸的是)目前影响了 Windows 上 Qt Creator 的每个用户。

因此,您必须在每次更改项目文件后调用 qmake - 例如,每次添加或修改源文件时。

有一个简单的解决方法 - 添加一个调用基础 Makefile 的构建步骤到项目配置的构建中。

关于c++ - 具有虚函数的未解析外部符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32168159/

相关文章:

python - 从 Python 调用时外部命令失败并返回代码 0xC0000005 但在控制台中有效

c++ - 在 C++ 中用于初始化二维数组的 C 嵌套数组指示符的最佳替代方法是什么?

c++ - 如果我让类(class)成员公开怎么办?

c++ - 在 OpenGL 中填充自相交多边形

qt - 如何在 QML 中使用 QFlags?

javascript - 包括 HTML 页面和样式吗?

c++ - 比较 argv 和 L"test"不工作

c++ - 如何覆盖基类的 (->) 运算符的成员

c++ - 添加到布局时 QGLWidget 崩溃

methods - Plone/Zope 的外部方法