简体   繁体   English

C ++未定义对头文件外部定义的成员函数的引用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM