0

これは私にはまったく不思議です。私はubuntuでg++を使用していますが、これは私のコードの一部です(クラス名は変更されていますが、まだどこでもスタブを使用しているため、他には何もありません):

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

私はこのような別のファイルに実装しました:

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()
{

}

そして私はそれをこのように使用しました:

main.cpp

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::BobBob::~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にはaの言及がなかったため、Bob.cppでは定義されていませんでしたBob<Alice>。Bob.cppがBob.oにコンパイルされるタイミングを定義するために使用できるテンプレートがありましたが、そうではありませんでした。Bob<Alice>

テンプレート定義をBob.hppまたはBob<Alice>Bob.cppに配置します。

于 2010-08-03T19:37:20.007 に答える