【问题标题】:Something wrong with linking链接有问题
【发布时间】:2011-09-26 19:21:08
【问题描述】:

我有 3 个 C++ 文件: genericStack.h:

template <class T> 
class Stack{
 public:
  Stack (int size){
    top = -1;
    MAX_SIZE = size;
    v = new T (size);
  }
  ~Stack(){ delete v;}

  T pop();
  void push (T);

  class Underflow{};
  class Overflow{};

  private:
   int top;
   int MAX_SIZE;
   T* v;
 };

genericStackImpl.c++:

#include "genericStack.h"

template <class T>
void Stack <T> :: push (T c){ 
  if (top == MAX_SIZE - 1) throw Overflow();
  v[++top] = c;
} 

template <class T>
T Stack <T> :: pop(){
  if (top < 0) throw Underflow();
  return v[top--];
}

driver.c++:

#include <iostream>
#include "genericStack.h"
int main(){
 Stack<char> sc(3);
 try{
   while (true) sc.push ('p');
 }
 catch (Stack<char>::Overflow){std::cout << "Overflow caught\n";}
 try{
  while (true) std::cout << sc.pop() << '\n';
 }
 catch (Stack<char>::Underflow){ std::cout << "Underflow caught\n";}
 return 0;
}

当我使用 g++ 4.5 编译时:

g++ -o driver driver.c++ genericStackImpl.c++

我收到以下错误:

/tmp/ccLXRXgF.o: In function `main':
driver.c++:(.text+0x2e): undefined reference to `Stack<char>::push(char)'
driver.c++:(.text+0x3c): undefined reference to `Stack<char>::pop()'
collect2: ld returned 1 exit status

我不明白问题是什么。如果我在驱动程序文件中移动实现,那么它会编译并运行。

【问题讨论】:

标签: c++ g++ linker-errors


【解决方案1】:

一般来说,模板定义也需要在头文件中。一个例外是当您显式实例化或使用显式特化时,您都没有这样做。

解决此问题的一种方法是将genericStackImpl.c++ 的内容移动到其头文件的底部。

这是因为模板函数不是实际的函数,它们只是模板。使用(实例化)模板来创建 实际 函数,这些是您链接的对象。

genericStackImpl.c++ 中没有函数。这些函数只有在您使用它们时才会创建,即编译器第一次看到sc.pushsc.pop。不幸的是,当driver.c++ 尝试创建这些函数时,它找不到模板主体——它们隐藏在genericStackImpl.c++ 中!相反,它只是编译对这些函数的引用,希望其他文件能够生成它们。

最后,当涉及到链接时间时,链接器在任何地方都找不到函数,所以它给你一个错误。

解决此问题的另一种方法是在genericStackImpl.c++ 中自己显式实例化这些函数,即

template class Stack<char>;

这将创建函数,链接器会找到它们。

这种方法的问题在于,它要求您事先知道要在堆栈中使用什么类型,因此大多数人只是将模板定义放在头文件中。

【讨论】:

  • 显式实例化?我不明白。
  • @Abhi:查看我的编辑。希望这可以解释它。我假设您知道编译链接过程是如何工作的。如果没有,您最好阅读链接的工作原理。
猜你喜欢
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2014-04-24
  • 1970-01-01
  • 2010-12-20
  • 2011-01-23
  • 2013-12-13
相关资源
最近更新 更多