0

そこで、基本的な VC++ プログラムを作成し、1 つのメソッド (コンストラクターとデストラクター以外) を持つテンプレート クラスを作成しました。次のエラーが表示されます。

>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Vector<int>::~Vector<int>(void)" (??1?$Vector@H@@QAE@XZ) referenced in function _main
>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Vector<int>::Vector<int>(int)" (??0?$Vector@H@@QAE@H@Z) referenced in function _main
>c:\users\edy\documents\visual studio 2010\Projects\ex01\Debug\ex01.exe : fatal error LNK1120: 2 unresolved externals

これが私のコードです:

(CPP クラスファイル)

using namespace std;
#include "Vector.h"
template <class T> Vector<T>::Vector(int n)
{
    this.crt = 0;
    this.dim = n;
    this.elem = new T[100];
}

template <class T> void Vector<T>::add(T e)
{
    this.elem[crt] = e;
    this.crt++;
}

template <class T> Vector<T>::~Vector(void)
{
    this.crt = 0;
}

(Hクラスファイル)

#pragma once
template <class T> class Vector
{
    public:
        int dim;
        T* elem;

        Vector(int n);
        void add(T e);
        ~Vector(void);

    private:
        int crt;
};

(メインファイル)

using namespace std;
#include "Vector.h"

int main(void)
{
    Vector<int> x(5);
    //x.add(1);    <--- if i decomment this line, it throws an additional error
    return 0;
}

ほとんどのソリューションには実装されていないメソッドが含まれていましたが、すべてのメソッドが実装されています。何が問題なのかわかりません。何か助けはありますか?

4

2 に答える 2

5

テンプレート クラスの実装は、それらを使用するすべての翻訳単位から見える必要があります。実装をヘッダー ファイルに移動します。

質問する前に - いいえ、クラスの専門分野を事前に知っていない限り、それらを非表示にする方法はありません。ジェネリックにしたい場合Vectorは、実装を可視にする必要があります。

それらを分離したい場合、通常の方法は.impl、ヘッダーに含めるファイルに実装を含めることです。

于 2012-06-18T21:46:04.233 に答える
1

テンプレートをファイルに実装する場合は.cpp、テンプレートの明示的なインスタンス化も提供する必要があります。テンプレートの.cppファイルに次を追加できます。

class template Vector<int>;

底に。intこれにより、ベクター テンプレートのバージョンがインスタンス化されます。ただし、ルシアンのアドバイスに従うと、テンプレートが使いやすくなります。彼が提案するようにすれば、コンパイラは、Vector<>さまざまな型で使用するときにオンデマンドでインスタンス化を作成します。ファイルに残しておくと.cpp、異なる種類の を作成するたびに、明示的なインスタンス化を追加する必要がありますVector<>

オブジェクトファイルの異なるセットが同じテンプレートのインスタンス化を何度も使用する場合、コンパイラは同じ数のインスタンス化を作成する可能性があるため、明示的なインスタンス化は暗黙的なインスタンス化よりも「無駄が少ない」と考える人もいます。ただし、リンカーは、実行可能ファイルが一緒にリンクされるときに、重複したインスタンス化を最終的に削除します。それでも、複数の共有ライブラリが同じテンプレートを同じパラメーターで再利用した場合、ダイナミック リンカーによってクリーンアップされても、膨張は持続します。実行可能ファイルのロード時間が重要な場合、これが明示的なインスタンス化を優先する理由になる可能性があります。非常に大規模なプロジェクトがあり、ビルドとリンクの時間が問題になる場合、これも明示的なインスタンス化を優先する理由になる可能性があります。

それ以外の場合は、暗黙的なインスタンス化に固執する必要があります。

于 2012-06-18T21:48:02.967 に答える