我有一个大型项目(20多个文件),但我设法设置了这个小例子,它重现了我的问题。基本上我有一个文件(A.cpp
)包括第二个文件(B.cpp
),但第二个文件需要第一个文件中的几个变量和函数。观察:
A.H:
#ifndef _A_H_
#define _A_H_
static void foo(int _something);
#endif // #ifndef _A_H_
A.cpp:
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
static void foo(int _something)
{
cout << _something << "\n";
}
int main(int argc, char *argv[])
{
B *b;
foo ( 123 ); // So we don't get that pesky defined-not-used warning
b = new B ();
b->display ( 123 );
}
B.h:
#ifndef _B_H_
#define _B_H_
#include "A.h"
class B
{
public:
B();
~B();
void display ( int x );
};
#endif // #ifndef _B_H_
B.cpp:
#include "B.h"
void B::display ( int x )
{
foo ( x );
}
我正在编译它,g++ -Wall A.cpp B.cpp -o main
但是我得到了这个错误:
A.h:3:13: warning: ‘void foo(int)’ used but never defined [enabled by default]
/tmp/ccFwfZa6.o: In function `main':
A.cpp:(.text+0x54): undefined reference to `B::B()'
/tmp/ccM8SNBK.o: In function `B::display(int)':
B.cpp:(.text+0xd): undefined reference to `foo(int)'
collect2: ld returned 1 exit status
我可以说这是一个链接错误,但我不知道为什么我会收到这个错误。
修改
在我的原始代码中,我仍然收到错误,这次是关于整数的多重定义,这是我得到的错误:
B.o:(.bss+0x4): multiple definition of `some_var'
A.o:(.bss+0x4034): first defined here
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
我正在创建变量some_var
,如此
A.H:
#ifndef _A_H_
#define _A_H_
static void foo(int _something);
int some_var;
#endif // #ifndef _A_H_
当我有那些有条件的警卫时,some_var
怎么可能被多次定义?
答案 0 :(得分:3)
你根本没有B :: B()身体。添加一个,不要忘记析构函数。
另外,从foo()中删除静态。
答案 1 :(得分:1)
问题现在是#include
s a.h
得到int some_var;
定义的每个源文件。通常,变量应在标题中声明,在一个源文件中定义。所以在你的标题中你需要
extern int some_var;
并在一个源文件中(大概是a.cpp)
int some_var;
答案 2 :(得分:0)
感谢Pete Becker我找出了问题,主要是因为缺乏对C / C ++所有事物的理解。
extern
语句不仅仅用于引用其他头文件的头文件中(即“Bh”编写extern int a
,其中a
在“Ac”中定义但是也在原始头文件中(在本例中为“啊”)int a = 1
),而int a
也是定义。因此,我在“A.h”中定义我的变量时,我应该在“A.h”中声明它extern int a
。undefined reference to a
(我确实认为编译器和链接器正在进行小便)。我正在“A.cpp”中搜索int a=...
,并且正在定义它的日期。事实证明这个定义是里面一个函数,因此永远不会被定义。