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

何が起こっているのか教えていただけますか?すべてのコード スニペットを 1 つのファイルにバインドすると、エラーは発生せず、意図したとおりに完全に機能します。extern キーワードをどこかに導入する必要があると思いますが、その方法がわかりません。

私のコンパイラは

i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Apple Inc. ビルド 5658 に基づく) (LLVM ビルド 2336.11.00)

「base.hpp」

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

};

「derive1.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;
  }    

};

「derive1.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;
}

「derive2.hpp」

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

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

「derive2.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;
}

"derive_test.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 に答える