Qt creator: c++:对Class::Function的未定义引用

Qt creator: c++: undefined reference to Class::Function

本文关键字:未定义 Function 引用 creator c++ Qt Class      更新时间:2023-10-16

我在Qt creator中创建了两个c++项目。一个是Application project,另一个是unit-test project。这两个项目单独运行良好。然而,当将两者联系在一起时,我遇到了一个小问题。

我在unit-test project中包括.pro file中的#INCLUDEPATH applicationProjectPath。然后是unit-test projectmain.cpp中的应用项目#include myClass。然后,从myClass创建myObject,并在该对象中调用一个函数。

编译时,出现以下错误:

undefined reference to `myObject::function' 

然而,当将#SOURCES applicationProjectPath/myClass.cpp添加到单元测试项目的.pro文件时(同时保留#INCLUDEPATH applicationProjectPath),一切都在工作(即:测试单元被执行)

当从.pro中删除#INCLUDEPATH时,它再次崩溃。

我想如果我包括#SOURCES,那么我不需要包括#INCLUDEPATH。如果我包括#INCLUDEPATH,我不应该包括#SOURCES(至少不是完整路径,只是.cpp文件,然后编译器应该寻找两个目录,默认的一个和添加的一个)。

那么,我的问题是:为什么会发生这种情况

您的单元测试将需要编译您想要进行单元测试的项目中的类。因此,您需要在两个项目中都添加include(否则测试项目将不知道您要测试的类)。并且链接器还需要链接到项目的代码,因为您的测试将使用这些类。

一种方法是在你的测试项目中添加你想要测试的类,并在你编译单元测试项目时再次编译它们,但这很繁琐,而且不太方便,因为每次你想要添加一个类时,你都需要将它添加到两个。pro文件中(提示,你可以在。pro文件中使用通配符,如*.cpp将文件夹中的所有源文件添加到项目中)。

在我看来,一个更好的方法是将你想要测试的项目设置为一个静态库,将它与应用程序分开:你有另一个项目,它是一个应用程序,只包含链接到该静态库的main.cpp

下面是包含项目的文件夹的表示:

Project.pro #subdir project
UIProject/ #static lib
    UIProject.pro
    #all your classes here
MainProject/ #application
    MainProject.pro
    main.cpp
UITestProject/ #unit tests of UIProject (linking to it)
    UITestProject.pro
    #all your UI test classes here

Project.pro:

TEMPLATE = subdirs
SUBDIRS += UIProject
SUBDIRS += MainProject
SUBDIRS += UITestProject

UIProject.pro:

# project type
TEMPLATE = lib
# library type
CONFIG += staticlib
HEADERS += *.h
SOURCES += *.cpp

MainProject.pro:

#[...]
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH += ../UIProject/
DEPENDPATH += $${INCLUDEPATH} # force rebuild if the headers change
# link against UILib
_UI_LIB = ../UIProject/
CONFIG(debug, debug|release) {
    win32: _UI_LIB = $$join(_UI_LIB,,,debug/UIProject.lib)
} else {
    win32: _UI_LIB = $$join(_UI_LIB,,,release/UIProject.lib)
}
LIBS += $${_UI_LIB}
PRE_TARGETDEPS += $${_UI_LIB}

UITestProject.pro:

#[...]
TEMPLATE = app
HEADERS += *.h
SOURCES += *.cpp
INCLUDEPATH += ../UIProject/
DEPENDPATH += $${INCLUDEPATH} # force rebuild if the headers change
# link against UILib
_UI_LIB = ../UIProject/
CONFIG(debug, debug|release) {
    win32: _UI_LIB = $$join(_UI_LIB,,,debug/UIProject.lib)
} else {
    win32: _UI_LIB = $$join(_UI_LIB,,,release/UIProject.lib)
}
LIBS += $${_UI_LIB}
PRE_TARGETDEPS += $${_UI_LIB}

你必须编辑它来匹配你的项目,但主要的东西在这里。它应该工作,因为我从我的一个项目复制它,提供我没有添加任何错误。

您应该将您的CPP文件包含到项目中,以告诉构建系统(qmake)编译给定的文件。

当您将myClass.cpp添加到测试项目时,它会被编译,否则不会。

所以,当你不添加cpp文件到项目中,你会得到链接器错误。

include只是单独处理

当你添加INCLUDEPATH的新路径时,编译器会将该路径添加到头文件搜索列表

当你将applicationProjectPath添加到include路径时,编译器将在那里搜索头文件。这很重要,因为它允许编译器找到myClass.h

如果你不添加路径到头搜索列表,编译器将无法编译你的main.cpp,你会得到编译错误。

但是,您可以在测试项目的主目录中指定myClass.h的(相对)路径:

#include "../applicationProjectPath/myClass.h"

总结

你需要添加你的源文件到测试项目添加你的头路径到测试项目的包含搜索列表

进一步阅读

什么是未定义的引用/未解析的外部符号错误,我如何修复它?

当您以错误的方式使用inline时,有时Qt会显示此错误,因此请检查您的inline 'd功能。