1

我的代码是:

测试.cpp

#include<iostream>
#include<boost/bind.hpp>
#include "extern.h"
using namespace std;
using namespace boost;
int fun(int x,int y){return x+y;}
/*
 *void add(int &m,int &n);
 */
int main(){
    int m=1;int n=2;
    cout << m << "  "<< n << endl;
    add(m,n);
    cout << m << "  "<< n << endl;
    return 0;

}

外部.h:

#include<iostream>
#include<boost/bind.hpp>
using namespace std;
using namespace boost;
void add(int &n,int &m);

外部.cpp:

#include<iostream>
#include<boost/bind.hpp>
using namespace std;
using namespace boost;

extern int m;
extern int n;

void add(int &n,int &m) {
    n = n+1;
    m = m+1;
}

当我编译它时

g++ -Wall -o test test.cpp

结果是:

/tmp/ccMHVRNo.o: In function `main':
test.cpp:(.text+0x7b): undefined reference to `add(int&, int&)'
collect2: ld returned 1 exit status

但是当我编译它时:

g++ -Wall -o test test.cpp extern.cpp

它运作良好:

$ ./test
1  2
2  3

所以原因是test.cpp找不到add()函数的实现。

但是我已经补充extern.htest.cpp,为什么它仍然说“未定义的引用add(int&, int&)”?

4

3 回答 3

3

该函数的实现void add(int&,int&)在源文件 extern.cpp 中。除非您告诉编译器,否则编译器无法知道此文件与程序相关。

您必须在命令行中指定所有源文件:

g++ -Wall -o test test.cpp extern.cpp

如果要避免编译所有源文件,还可以指定已编译的目标文件:

g++ -Wall -o test test.cpp extern.o

当您不想每次都考虑需要编译哪些命令时,您应该使用 make 并创建一个Makefilewith 规则来定义目标的构建方式。有了makefile,你就可以开始了

make

并得到结果。

于 2013-06-06T14:39:24.307 回答
3

头文件extern.h只告诉你的程序函数的原型是如何制作的。链接器需要函数的实际实现,因此它会查找代码add(int&,int&)引用,并且它无法找到它,除非您向编译器提供它需要的所有文件(在这种情况下,extern.cpp是链接器在查找add功能)。

于 2013-06-06T14:40:07.990 回答
1

这是通常的公式:

g++ -Wall -c test.cpp
g++ -Wall -c extern.cpp
g++ -o test test.o extern.o

有单线,但它们不能很好地扩展到更大的项目。

于 2013-06-06T14:41:22.933 回答