c ++ undefined对头文件外定义的成员函数的引用

时间:2014-08-08 21:50:09

标签: c++ class g++ undefined-reference member-functions

我的印象是,您可以在一个文件中定义类的成员函数,然后在另一个文件中使用这些函数,只要这两个文件都被编译并发送到链接器即可。但是,如果我使用g ++(4.6.4),这样做会给我一个未定义的引用错误。有趣的是,使用intel编译器(icpc 11.0)不会出错,一切正常。是否有一些我可以用g ++设置的标志来使这个工作,或者是英特尔编译器让我逃避我不应该做的事情?以下是一些可以重现我的问题的代码:

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:

#include "class.h"

void Test::set(int x, int y)
{
    a = x;
    b = y;
}

int Test::add(void)
{
    return a+b;
}

main.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

1 个答案:

答案 0 :(得分:5)

好的,这很奇怪,但发生的事情是这个结构:

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

这就是链接器无法找到符号的原因。

  

修改:至于为什么会发生这种情况,似乎是由于解释标准如何指定typedef名称作为类的处理方式的问题 - 名称的。较新的编译器似乎没有表现出相同的问题。这个问题中报告的问题是用g ++ 4.4.7复制的。

如果您将class.cpp文件中的代码移至main.cpp并仅编译main.cpp,那么事情就会奏效。或者,您可以将方法定义内联到class.h

如果您想将它们保留为单独的翻译单元,则需要更改class.h文件,以便使用class Test方式定义您的课程,而不是使用typedef匿名课。