首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt创建者: c++:对Class::Function的未定义引用

Qt创建者: c++:对Class::Function的未定义引用
EN

Stack Overflow用户
提问于 2013-06-04 20:20:10
回答 2查看 40.7K关注 0票数 4

我正在我的Qt创建器中创建两个c++项目。第一个是Application project,另一个是unit-test project。这两个项目分别工作得很好。然而,当将两者联系在一起时,我遇到了一个小问题。

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

编译时,出现以下错误:

代码语言:javascript
复制
undefined reference to `myObject::function' 

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

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

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-04 20:55:39

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

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

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

以下是包含项目的文件夹的表示形式:

代码语言:javascript
复制
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:

代码语言:javascript
复制
TEMPLATE = subdirs
SUBDIRS += UIProject
SUBDIRS += MainProject
SUBDIRS += UITestProject

UIProject.pro:

代码语言:javascript
复制
# project type
TEMPLATE = lib

# library type
CONFIG += staticlib

HEADERS += *.h
SOURCES += *.cpp

MainProject.pro:

代码语言:javascript
复制
#[...]
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:

代码语言:javascript
复制
#[...]
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}

您必须对其进行编辑以匹配您的项目,但主要内容在这里。如果我没有添加任何错误,它应该可以像我从我的一个项目中复制的那样工作。

票数 4
EN

Stack Overflow用户

发布于 2013-06-04 20:43:33

您应该将cpp文件包含到项目中,以告诉build system (qmake)编译给定的文件。

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

因此,当您不将cpp文件添加到项目中时,您将得到链接器错误。

Include只是单独处理

当您向INCLUDEPATH添加新路径时,编译器会将该路径添加到headers搜索列表

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

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

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

代码语言:javascript
复制
#include "../applicationProjectPath/myClass.h"

总结

您需要将源文件添加到测试项目,并将头文件路径添加到测试项目的包含搜索列表。

进一步阅读

What is an undefined reference/unresolved external symbol error and how do I fix it?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16917677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档