none
如何声明模板类 RRS feed

  • 问题


  • 导入静态lib, 没有头文件。 要用lib文件中的方法,我要声明需要用到的类和类中的方法。这个类是模板类,下面是代码和我的步骤
    1. 新建了SmartDevice 的win32 smart device console project.
    2. 在DeleteDB.cpp 文件中导入lib文件:#pragma comment(lib, "DataProviderLib.lib")
    1. 新建了一个头文件DBV.h,声明我需要使用的模板类
    #ifndef DBVECTOR_H
    #define DBVECTOR_H
    #define SAFE_ENTER_CS(CS) if(m_bInit) {EnterCriticalSection(CS);}
    #define SAFE_LEAVE_CS(CS) if(m_bInit) {LeaveCriticalSection(CS);}

    template <class Object>
    class DBVec
    {
      public:
        explicit DBVec();
        DBVec( const DBVec& rhs ) ;
        ~DBVec( );
        BOOL empty();
    };
    #endif

    然后在cpp文件的_tmain方法中调用

    enum myStructType { PHOTO = 1, 
          COMMENT = 2, };

    int _tmain(int argc, _TCHAR* argv[])
    {
       int i = 0;
     
     CDBVec <myStructType> DBInt;
     if (DBInt.empty())
     {
             i = 1;
     }

     return 0;
    }


    编译的时候报错:
    error LNK2019: unresolved external symbol "public: __cdecl CDBVec<enum myStructType>::~CDBVec<enum myStructType>(void)" (??1?$CDBVec@W4myStructType@@@@QAA@XZ) referenced in function wmain
    1>DeleteDBDemo.obj : error LNK2019: unresolved external symbol "public: int __cdecl CDBVec<enum myStructType>::empty(void)" (?empty@?$CDBVec@W4myStructType@@@@QAAHXZ) referenced in function wmain
    1>DeleteDBDemo.obj : error LNK2019: unresolved external symbol "public: __cdecl CDBVec<enum myStructType>::CDBVec<enum myStructType>(void)" (??0?$CDBVec@W4myStructType@@@@QAA@XZ) referenced in function wmain
    1>Windows Mobile 5.0 Pocket PC SDK (ARMV4I)\Debug/DeleteDBDemo.exe : fatal error LNK1120: 3 unresolved externals


    这个错误信息的意思应该是说无法调用外部链接的函数,是我的声明有错吗,我核对过我要用的函数,是一样的。 还是模板类不能这么用?

    2009年7月16日 12:54

答案

  • 你的用法是不对的.

    模板代码的生成是在编译的时候发生的,模板其实就相当于C的#define.若要使用公用的模板类必须提供模板代码.然后编译才可以.

    就是说,在你的lib内部,并不存在原来的模板,而只存在你编译后实例化的模板.
    template <class Object>
    class DBVec
    {
      public:
        explicit DBVec();
        DBVec( const DBVec& rhs ) ;
        ~DBVec( );
        BOOL empty();
    };

    像这个,编译成静态库的时候必须要把它实例化,比如DBVec<TypeA>,然后你的外部程序要调用这个lib的时候只能调用DBVec<TypeA>,若你调用DBVec<TypeB>而这个是没有实例化到lib里面的,肯定会链接失败。
    0xBAADF00D
    • 已标记为答案 MinghuaYao 2009年7月20日 14:52
    2009年7月17日 13:15
    版主

全部回复

  • 在C++03中,模板类中的函数定义需要写在类的定义中,否则模板类无法聚现。


    在C++0x中可以写到类定义的外面,但是要求与类定义在同一个文件中。


    麻烦把正确答案设为解答。
    2009年7月17日 2:13
    版主
  • 你的用法是不对的.

    模板代码的生成是在编译的时候发生的,模板其实就相当于C的#define.若要使用公用的模板类必须提供模板代码.然后编译才可以.

    就是说,在你的lib内部,并不存在原来的模板,而只存在你编译后实例化的模板.
    template <class Object>
    class DBVec
    {
      public:
        explicit DBVec();
        DBVec( const DBVec& rhs ) ;
        ~DBVec( );
        BOOL empty();
    };

    像这个,编译成静态库的时候必须要把它实例化,比如DBVec<TypeA>,然后你的外部程序要调用这个lib的时候只能调用DBVec<TypeA>,若你调用DBVec<TypeB>而这个是没有实例化到lib里面的,肯定会链接失败。
    0xBAADF00D
    • 已标记为答案 MinghuaYao 2009年7月20日 14:52
    2009年7月17日 13:15
    版主
  • 谢谢两位^_^

    2009年7月20日 14:52