未定义的引用与模板化类的成员实现

时间:2010-08-03 19:20:35

标签: c++ templates undefined-reference

这对我来说是神秘的。我在ubuntu上使用g ++,这是我的一些代码(类名更改,但没有其他因为我仍在使用存根):

Bob.hpp

template <class A>
class Bob : public Jack<Chris, A>
{
    public: 

        Bob(int x1, int x2, float x3 = 1.0, float x4 = 2.0, float x5 = 3.0) throw(Exception);
        virtual ~Bob();
};

我在另一个文件中实现了这样的:

Bob.cpp

template <class A>
Bob<A>::Bob(int x1, int x2, float x3, float x4, float x5) throw(Exception)
{

}

template <class A>
Bob<A>::~Bob()
{

}

我用过这样的话:

的main.cpp

int main()
{
    Bob<Alice> instance(1, 2);
}

编译:

g++ -c Bob.cpp -o Bob.o
g++ -c main.cpp -o main.o
g++ -L"libs" -llib main.o Bob.o prog

给了我     main.o:在函数main': main.cpp:(.text+0x1fd): undefined reference to Bob :: Bob(int,int,float,float,float)'     collect2:ld返回1退出状态

我完全难过了。使用g ++链接阶段更改顺序没有任何区别。编译目标文件不会产生任何问题。为什么在实现构造函数时未定义引用?如果有人能对此有所了解,我们将不胜感激。

4 个答案:

答案 0 :(得分:1)

类模板成员函数的声明和定义应该都在同一个头文件中。

编译Bob.cpp时,编译器同时具有声明和定义。此时,编译器不需要为模板类生成任何定义,因为没有实例化。当编译器编译main.cpp时,会有一个实例化:模板类Bob<Alice>。此时编译器具有声明但没有定义!

答案 1 :(得分:1)

您需要将代码从Bob.cpp移动到Bob.hpp中。当编译器在Bob.cpp中看到Bob::BobBob::~Bob的定义时,它不知道实际将要实例化哪些类型的Bob(即Bob<int> vs Bob<SomeClass>并且不生成它们的代码。    或者,您仍然可以将代码放在Bob.cpp文件中,但是您需要声明将要实例化哪些类型的Bob,例如: 在Bob.cpp里面:

template
class Bob<Alice>;

答案 2 :(得分:0)

除了其他人提出的问题之外,图书馆必须在GCC命令行上排在最后。而不是:

g++ -L"libs" -llib main.o Bob.o prog

你想要:

g++ -L"libs"  main.o Bob.o prog -llib

答案 3 :(得分:0)

您认为Bob<Alice>的构造函数应该在哪里定义?它没有在Bob.cpp中定义,因为在Bob.cpp中没有提到Bob<Alice>。有一个模板,当Bob.cpp编译成Bob.o时,可以用来定义Bob<Alice>,但事实并非如此。

将模板定义放在Bob.hpp中,或将Bob<Alice>放在Bob.cpp。