2011-07-13 66 views
1

链接时出现以下错误。“未定义的引用”错误。 (从成员函数到静态成员变量)

无法从函数ClassBB :: bound()访问成员变量ClassBB :: THR。从ClassBB :: setThreshold(T v)函数看来,它与ClassBB :: bound()在相同条件下都是模板成员函数,ClassBB :: THR被成功访问(I'当然,m只谈论编译时间)。

我还是新来的C++,特别是在模板架构。谢谢!

环境:Ubuntu的10.10,G ++ 4.4.5通过Eclipse靛蓝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

对不起,现在它被添加为Code-C,其中ClassBB 被实例化。 – IsaacS

+0

我编辑过问题标题,因为该错误不会发生在非静态成员变量中。 –

回答

7

您必须为静态变量创建存储。只需添加:

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

注意,对于正常的成员变量,每当创建模板类的新实例生成存储。但是对于静态成员,应该为它们定义一个“静态”的地方,因此是明确的定义。

+0

问题。假设这个模板被用于两个不同源文件中的同一个类。然后,静态变量将被定义在两个不同的源文件中。那么这不会在链接阶段造成错误吗?像变量一样定义两次? (我不记得确切的消息,只是我似乎记得这种问题)。 –

+0

@John:不,编译器为链接时合并在一起的模板静态变量发出特殊的* weak *符号。 –

+0

优秀!谢谢,现在我知道如何为模板做静力学! –

4

您需要定义静态变量。

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

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