- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我的印象是,您可以在一个文件中定义一个类的成员函数,然后在另一个文件中使用这些函数,只要两个文件都被编译并发送到链接器即可。但是,如果我使用 g++ (4.6.4),这样做会给我一个 undefined reference 错误。有趣的是,使用 intel 编译器 (icpc 11.0) 不会报错,一切正常。是否有一些我可以在 g++ 中设置的标志来完成这项工作,或者是英特尔编译器让我摆脱了我不应该做的事情?这是一些重现我的问题的代码:
类.h:
#ifndef _H
#define _H
typedef class
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
} Test;
#endif
类.cpp:
#include "class.h"
void Test::set(int x, int y)
{
a = x;
b = y;
}
int Test::add(void)
{
return a+b;
}
主要.cpp:
#include <cstdio>
#include "class.h"
int main(void)
{
Test n;
n.set(3, 4);
printf("%d\n", n.add());
return 0;
}
为了编译,我这样做:
$ 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
最佳答案
好吧,这很奇怪,但发生的是这个结构:
typedef class
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
} Test;
虽然 legal 在语义上不被编译器视为:
class Test
{
public:
int a;
int b;
void set(int x, int y);
int add(void);
};
typedef
版本使您的方法对文件static
,如 nm
输出所示:
$ nm class.o
0000000000000024 t _ZN4Test3addEv
0000000000000000 t _ZN4Test3setEii
U __gxx_personality_v0
虽然 class Test
版本使它们成为正确的方法:
$ nm class2.o
0000000000000024 T _ZN4Test3addEv
0000000000000000 T _ZN4Test3setEii
U __gxx_personality_v0
这就是链接器找不到符号的原因。
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. Newer compilers do not seem to exhibit the same issue. The problem reported in this question was reproduced with g++ 4.4.7.
如果您将 class.cpp
文件中的代码移动到 main.cpp
中,并且只编译 main.cpp
,一切都会正常进行。或者,您可以将方法定义内联到 class.h
中。
如果您想将它们保留为单独的翻译单元,您需要更改 class.h
文件,以便使用 class Test
方式定义您的类,而不是在匿名类上使用 typedef
。
关于c++未定义对头文件外部定义的成员函数的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25212760/
我是一名优秀的程序员,十分优秀!