2011-07-13 11 views
1

リンク時に次のエラーが発生しました。"未定義参照"エラー。 (メンバー関数から静的メンバー変数へ)

メンバ変数ClassBB :: THRは、ClassBB :: bound()関数からアクセスできません。

奇妙なのは、両方ともテンプレートメンバー関数でClassBB :: THRが正常にアクセスされているという点でClassBB :: bound()と同じ状態に見えるClassBB :: setThreshold(T v)もちろん、コンパイル時間についてだけ話しています)。

私はまだC + +の初心者です。特にテンプレートアーキテクチャーです。ありがとう!

環境:のUbuntu 10.10、G ++ 4.4.5

エクリプスインディゴCDTを介してエラーMSG(のみリンカーの一部):

Building target: SampleEclipsePrj 
Invoking: GCC C++ Linker 
g++ -L/usr/local/lib -L/usr/lib -o "SampleEclipsePrj" ./src/SampleEclipsePrjFinal/IntersectAngle.o ./src/SampleEclipsePrjFinal/ReadRealTime.o ./src/SampleEclipsePrjFinal/SampleEclipsePrj.o ./src/SampleEclipsePrjFinal/SampleEclipsePrjThread.o ./src/SampleEclipsePrjFinal/Slope.o ./src/SampleEclipsePrjFinal/Transform.o ./src/SampleEclipsePrjFinal/Utility.o ./src/SampleEclipsePrjFinal/main3_linux.o ./src/SampleEclipsePrjFinal/reader.o -lcv -lcxcore -lhighgui 
./src/SampleEclipsePrjFinal/SampleEclipsePrj.o: In function `ClassBB<double>::bound()': 
/home/user/Documents/workspace_eclipse/SampleEclipsePrj/Includes/ClassBB.hpp:203: undefined reference to `ClassBB<double>::THR' 
/home/user/Documents/workspace_eclipse/SampleEclipsePrj/Includes/ClassBB.hpp:204: undefined reference to `ClassBB<double>::THR' 
/home/user/Documents/workspace_eclipse/SampleEclipsePrj/Includes/ClassBB.hpp:206: undefined reference to `ClassBB<double>::THR' 
/home/user/Documents/workspace_eclipse/SampleEclipsePrj/Includes/ClassBB.hpp:207: undefined reference to `ClassBB<double>::THR' 
collect2: ld returned 1 exit status 
make: *** [SampleEclipsePrj] Error 1 

**** Build Finished **** 

注:Eclipseと端末の両方で同じ結果を得ました。

(のみ関連する部分を表示するように切り取ら)コード-B:

#ifndef _BBOUND_H 
#define _BBOUND_H 

template<class T> 
class ClassBB 
{ 
     T *pMap; 
     float u1, v1, u2, v2; 
     int w, h; 

     float converge(float sp, float ep, float steps, float fixedPt, 
       float thr); 
     static T THR; 

    public: 
     ClassBB() : 
       pMap(NULL), u1(0), v1(0), u2(0), v2(0), w(0), h(0) 
     { 
     } 
     ClassBB(float U1, float V1, float U2, float V2); 
     static void setThreshold(T v); 
    int bound(); 
     ~ClassBB(); 
}; 

template<class T> 
ClassBB<T>::ClassBB(float U1, float V1, float U2, float V2) 
{// do something 
} 

template<class T> 
void ClassBB<T>::setThreshold(T v) 
{ 
    ClassBB::THR = v; 
} 

//Converge 
template<class T> 
float ClassBB<T>::converge(float sp, float ep, float step, float fixedPt, 
     float thr) 
{// do something 
    return point; 
} 
//The bound algorithm 
template<class T> 
int ClassBB<T>::bound() 
{ 
    u2 = converge(0.75, 0.5, 0.03125, v2, ClassBB::THR); 
    v2 = converge(0.25, 0.0, 0.03125, u2, THR); // Both don't work. 
    return 1; 
} 

template<class T> 
ClassBB<T>::~ClassBB() 
{// do something 
} 

#endif 

コード-C(クラスをインスタンス):

#ifndef _SCENE_CLASSIFIER_H 
#define _SCENE_CLASSIFIER_H 
#include "ClassBB.hpp" 

class ClassCC 
{ 
     ClassBB<double> bb; //Branch and Bound 

    public: 
     ClassCC(int W = 0, int H = 0); 
     ~ClassCC(); 
}; 
#endif 
+1

「ClassBB 」をインスタンス化するコードはどこですか? – wallyk

+0

申し訳ありませんが、ClassBB がインスタンス化されたCode-Cとして追加されました。 – IsaacS

+0

静的でないメンバー変数ではエラーが発生しないため、質問タイトルを編集しました。 –

答えて

7

静的変数用のストレージを作成する必要があります。

template<class T> T ClassBB<T>::THR; 

通常のメンバー変数では、テンプレートクラスの新しいインスタンスが作成されるたびにストレージが生成されることに注意してください。しかし、静的メンバーの場合は、静的メンバーを定義する必要があります。つまり、明示的定義です。

+0

質問。このテンプレートが2つの異なるソースファイルの同じクラスで使用されたとします。次に、静的変数は2つの異なるソースファイルで定義されます。リンクフェーズでエラーが発生しないでしょうか?変数のようなものが二度定義されていますか? (私は正確なメッセージを覚えていない、私はこの種の問題を思い出すように思える)。 –

+0

@John:いいえ、コンパイラは、リンク時に一緒にマージされるテンプレート化された静的変数に対して特殊な*弱い記号を出力します。 –

+0

優秀!ありがとう、今私はテンプレートのための静的を行う方法を知っている! –

4

あなたは静的変数を定義する必要があります。

template<class T> 
class ClassBB { 
    // ... 
    static T THR; 
    // ... 
}; 

template<class T> 
T ClassBB<T>::THR; 
関連する問題