0

全部。

我制作了一组c++代码如下。
然后,我通过 g++ 将每个编译成功.cpp。 但是,我得到了一个链接错误.o

 Undefined symbols for architecture x86_64:
  "derive1<3>::derive1(int)", referenced from:
      derive2::derive2(int)in derive2.o
      derive2::derive2(int)in derive2.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

你能告诉我发生了什么事吗?如果我将所有代码片段绑定在一个文件中,则不会出现任何错误,并且可以按我的预期完美运行。我想我应该在某处引入 extern 关键字,但我不知道该怎么做。

我的编译器是

i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2336.11.00)

“基地.hpp”

class base {
public:
  virtual int hoge( int num ) = 0;

};

“派生1.hpp”

#include "base.hpp"
#include <iostream>

template <int N>
class derive1 : public base {
public:
  explicit derive1( int n );
  virtual int hoge( int num ) {
    std::cout << "num = " << num << std::endl
          << "N = " << N << std::endl;
    return N;
  }    

};

“派生1.cpp”

#include "derive1.hpp"

template <int N>
derive1<N>::derive1 ( int n ) {
  std::cout << "This is the constructer of derive1" << std::endl
        << "N = " << N << ", n = " << n << std::endl;
}

“派生2.hpp”

#include "derive1.hpp"
#include <iostream>

class derive2 : public derive1<3> {
public:
  explicit derive2( int n );
};

“派生2.cpp”

#include "derive2.hpp"

derive2::derive2( int n ) : derive1<3>( n ) {
  std::cout << "This is the constructer of derive2" << std::endl
        << "n = " << n << std::endl;
}

“派生测试.cpp”

#include<iostream>
#include "derive2.hpp"

int main() {

  derive2 test(3);

  std::cout << "return value = "
        << test.hoge( 5 )
        << std::endl;
  return 0;
}
4

3 回答 3

1

简单的答案是您必须将所有模板化代码(derive1::derive1(int)等)放入头文件中,而不是放入它们自己的翻译单元中。编译器在尝试实例化模板时需要查看完整的定义。当然,您可以*.cpp文件中定义模板,但是您必须显式地专门化它并在头文件中声明该专门化。

于 2013-01-28T12:02:23.737 回答
1

您不应该为模板类拆分 .h 和 .cpp 文件的定义和实现。

什么是未定义的引用/未解决的外部符号错误,我该如何解决?

于 2013-01-28T11:58:06.927 回答
1

不幸的是,大多数编译器需要模板函数的实现(在这种情况下,template <int N> derive1<N>::derive1 ( int n )使用它的编译单元可以使用它。将它移动到“derive1.hpp”。

于 2013-01-28T11:59:06.670 回答