0

这对我来说非常神秘。我在 ubuntu 上使用 g++,这是我的一些代码(类名发生了变化,但没有别的,因为我仍在到处使用存根):

鲍勃.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();
};

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

鲍勃.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()
{

}

我像这样使用它:

主文件

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 toBob::Bob(int, int, float, float, float)' collect2: ld 返回 1 退出状态

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

4

4 回答 4

1

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

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

于 2010-08-03T19:24:14.910 回答
1

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

template
class Bob<Alice>;
于 2010-08-03T19:31:30.103 回答
0

除了其他人提出的问题外,库必须排在 GCC 命令行的最后。代替:

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

你要:

g++ -L"libs"  main.o Bob.o prog -llib
于 2010-08-03T19:28:20.353 回答
0

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

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

于 2010-08-03T19:37:20.007 回答