[英]c++ undefined reference to member function defined outside of header file
I am under the impression that you are allowed to define member functions of a class in one file and then use those functions in another file, as long as both files are compiled and sent to the linker. 我的印象是,只要两个文件都被编译并发送到链接器,就可以在一个文件中定义类的成员函数,然后在另一个文件中使用这些函数。 However, doing this gives me an undefined reference error if I use g++ (4.6.4).
但是,如果使用g ++(4.6.4),这样做会给我带来不确定的参考错误。 Interestingly, using the intel compiler (icpc 11.0) does not give an error and everything works.
有趣的是,使用intel编译器(icpc 11.0)不会产生错误,并且一切正常。 Is there some flag I can set in g++ to make this work, or is the intel compiler letting me get away with something I shouldn't be doing?
我可以在g ++中设置一些标志来使其工作吗,还是intel编译器让我摆脱不应该做的事情? Here is some code that reproduces my problem:
这是一些代码重现了我的问题:
class.h: class.h:
#ifndef _H
#define _H
typedef class
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
} Test;
#endif
class.cpp: class.cpp:
#include "class.h"
void Test::set(int x, int y)
{
a = x;
b = y;
}
int Test::add(void)
{
return a+b;
}
main.cpp: main.cpp中:
#include <cstdio>
#include "class.h"
int main(void)
{
Test n;
n.set(3, 4);
printf("%d\n", n.add());
return 0;
}
To compile, I do: 要编译,我这样做:
$ g++ class.cpp main.cpp -o test
/tmp/ccRxOI40.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `Test::set(int, int)'
main.cpp:(.text+0x26): undefined reference to `Test::add()'
collect2: ld returned 1 exit status
Okay, this is strange, but what happened is that this construct: 好的,这很奇怪,但是发生的是这个构造:
typedef class
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
} Test;
while legal is not being treated semantically the same by the compiler as: 虽然编译器在法律上未将Legal视为:
class Test
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
};
The typedef
version makes your methods static
to the file, as indicated in the nm
output: typedef
版本使您的方法对文件而言是static
的,如nm
输出所示:
$ nm class.o
0000000000000024 t _ZN4Test3addEv
0000000000000000 t _ZN4Test3setEii
U __gxx_personality_v0
While the class Test
version makes them proper methods: 虽然
class Test
版本使它们成为正确的方法:
$ nm class2.o
0000000000000024 T _ZN4Test3addEv
0000000000000000 T _ZN4Test3setEii
U __gxx_personality_v0
This is why the linker failed to find the symbols. 这就是链接器找不到符号的原因。
Edit: As to why this is happening, it seems to be due to an issue with interpreting how the Standard specifies the treatment of the
typedef
name as a class-name .编辑:至于为什么发生这种情况,这似乎是由于解释标准如何将
typedef
名称指定为class-name所引起的 。 Newer compilers do not seem to exhibit the same issue.较新的编译器似乎没有出现相同的问题。 The problem reported in this question was reproduced with g++ 4.4.7.
用g ++ 4.4.7复制了此问题中报告的问题。
If you move the code in your class.cpp
file into main.cpp
and only compile main.cpp
, things will work. 如果将
class.cpp
文件中的代码移动到main.cpp
并且仅编译main.cpp
,则一切正常。 Alternatively, you can inline the method definitions into class.h
. 或者,您可以将方法定义内联到
class.h
。
If you want to leave them as separate translation units, you need to change the class.h
file so that your class is defined using the class Test
way instead of using the typedef
on the anonymous class. 如果要将它们保留为单独的翻译单元,则需要更改
class.h
文件,以便使用class Test
方法而不是在匿名类上使用typedef
定义类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.