链接两个 .cpp 文件和一个 .h 文件

13

我正在做一项练习(来自Thinking in C++的第三章),但是我遇到了连接两个.cpp文件的问题。

这是练习题:

创建一个头文件(扩展名为“.h”)。在此文件中,通过从以下函数类型中变化参数列表和返回值之间进行选择:void、char、int和float,声明一组函数。现在,创建一个包含您的头文件并为所有这些函数创建定义的.cpp文件。每个函数定义应该简单地打印出函数名称、参数列表和返回类型,以便您知道它已被调用。创建一个包含您的头文件并定义int main()的第二个.cpp文件,其中包含对所有函数的调用。编译并运行程序。

我已经创建了三个文件,但当我尝试编译时,编译器给我这个错误:

undefined reference to `func1()'

undefined reference to `func2(int)'|

undefined reference to `func3(char, int, double)'|

undefined reference to `func4()'|

||=== Build finished: 4 errors, 0 warnings ===|

为什么找不到函数声明呢?

##EDIT
这是我的三个文件:

func_ex.h

void func1(void);
int func2(int i);
char func3(char c, int i, double d);
float func4(void);

func_ex.cpp

#include "func_ex.h"
using namespace std;

void func1(void) {
    cout << "void func1(void)" << endl;
}

int func2(int i) {
    cout << "int func2(int i)" << endl;
}

char func3(char c, int i, double d) {
    cout << "func3(char c, int i, double d)" << endl;
}

float func4(void) {
    cout << "func4(void)" << endl;
}

func_ex_main.cpp

#include "func_ex.h"
#include <iostream>
using namespace std;

int main(int argc, char* argv[]) {
    func1();
    int i;
    func2(i);
    char c; double d;
    func3(c, i, d);
    func4();
}

我使用GCC作为编译器(并且使用Code::Blocks作为IDE,但我认为这不重要)。


2
你是如何尝试编译程序的?看起来你没有编译/链接其中一个文件。 - templatetypedef
2
听起来你在错误地使用编译器。显而易见的解释是你没有告诉编译器关于你的第一个.cpp文件,所以它没有找到其中的任何函数声明。请发布更多关于你如何使用编译器的详细信息。 - john
1
@unNaturhal:你确定 Code::Blocks 项目中包含了你的两个 cpp 文件吗? - Nemanja Trifunovic
1
@ Nemanja:不,我不确定。老实说,我不知道我必须创建一个项目。但是现在我已经创建了它,并且一切都正常工作!:D - Overflowh
1
@john:我刚刚在func_ex.cpp中添加了<iostream>,谢谢。 - Overflowh
显示剩余8条评论
7个回答

12

听起来好像文件没有正确地找到函数。头文件是否在两个文件中都被包含了?你可以这样包含它:

#include "myheader.h"

您确定已经同时编译两个文件了吗?比如:

gcc -o myprogram file1.cpp file2.cpp

8
这会导致编译错误,而不是所描述的链接器错误。 - templatetypedef

9
gcc -c func_ex.cpp -o func_ex.o
gcc func_ex_main.cpp func_ex.o -o func_ex_main

0
code::blocks 中,默认设置是只编译一个文件。
以下是我解决这个问题的方法:
project -> properties -> build targets ->
Select files related in the bottom right section.

0
对于像我这样可能正在使用BloodShed Dev C ++ IDE的人。
创建一个项目文件夹,然后将您的H文件和CPP文件放置在项目文件夹中。
我遇到了与上述提到的相同的问题,我得出的结论是我的编译器只编译H文件,甚至不会读取与之链接的CPP文件。当我把它们放在项目文件夹中时,我的编译器会将所有文件一起编译,从而允许我的代码运行。
以下是创建Bloodshed使用者项目文件夹的链接。

http://www.horstmann.com/bigcpp/help/bloodshed/index.html

对于其他集成开发环境(IDE)的用户,我认为问题类似。如果有需要进一步说明的,请告诉我。

即使我按照你提供的链接进行操作,使用Dev C++进行简单的链接仍然遇到了问题。但是,这个讨论提供了额外的启示。关键在于添加一个项目文件夹,而不是普通文件夹,将源文件放入其中。这最终使得Dev C++能够像@xda1001的示例一样编译文件。 - Spencer Williams
好的,事实证明这里链接的指令完全没有问题,你不需要添加项目文件夹。我曾经在Dev-C++中拖放了一个文件,后来将其添加到我的项目中,但现在我看到它最初是在项目上下文之外尝试构建的原始文件。 - Spencer Williams

-1

我认为你应该在你的func_main.cpp中包含#include"func_x.cpp"


2
一般来说,不应该使用 #include 包含 .cpp 文件,它们应该被链接。在极少数情况下,如果您设计了一个需要 #include 的实现文件,我见过人们使用 .ipp 扩展名。具体来说,我在 boost 中看到过这种用法。 - Magnus Hoff

-1
首先,如果没有返回语句,你怎么能有func1()、func2()和func3()呢?试着把你的头文件体放在这些(#include guards)里面:
#ifndef func_ex.h
#define func_ex.h
/* your code */

#endif 

-3

你需要像这样放置一个包含文件:

#include "headerfilename.h"

在每个 .cpp 文件的顶部。


3
这会导致编译器错误,而不是所描述的链接器错误。 - templatetypedef

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接