毕业论文开发语言企业开发JAVA技术.NET技术WEB开发Linux/Unix数据库技术Windows平台移动平台嵌入式论文范文英语论文
您现在的位置: 毕业论文 >> 开发语言 >> 正文

无法解析的外部符号 "public: virtual __thiscall CachedObj<class Qi

更新时间:2013-1-28:  来源:毕业论文

无法解析的外部符号 "public: virtual __thiscall CachedObj<class Qi

定义一个含 operator new 和 operator delete 函数的基类(此类并不实际使用),然后将真正使用的类继承于这个基类,达到优化内存分配的目的。但是代码通不过编译。出错提示:

Main.obj : error LNK2001: 无法解析的外部符号 "public: virtual __thiscall CachedObj<class Qi>::~CachedObj<class Qi>(void)" (??1?$CachedObj@VQi@@@@UAE@XZ)
C:\Documents and Settings\Administrator\桌面\test\Debug\test.exe : fatal error LNK1120: 1 个无法解析的外部命令

/*为你的类实现一个类特定的内存分配器。测量性能的改变,看看到底有多大帮助。*/    #include<iostream> #include<memory>   /* 内存分配类:预先分配对象并维护一个未使用对象的自由列表。 当一个对象被释放, 它将放回自由列表,程序退出时才将内存返还给系统*/template<typename T> class CachedObj { public:     void* operator new(size_t);     void operator delete(void*,size_t);     virtual ~CachedObj(); protected:     T* next; // 指向下一个可用对象 private:     // static 成员管理自由列表。声明为 static,是因为只为所有给定类型的对象维持一个自由列表     static std::allocator<T> alloc_mem;     static void add_to_freelist(T*); //将对象加入自由列表(新分配和删除对象时调用)     static T* freeStore; // 指向自由列表表头     static const size_t chunk; // 自由列表为空时将分配的对象数目 }; template<typename T> std::allocator<T> CachedObj<T>:: alloc_mem; // 只定义,无需初始化 template<typename T> T* CachedObj<T>::freeStore = 0; // 列表首指针初始化为 0 template<typename T> const size_t CachedObj<T>::chunk = 50; // 每次分配数量初始化为 50     // new 从自由列表返回一个对象。new 应该只被要求建立一个 T, 而不是从 T 派生一个对象 template<typename T> void* CachedObj<T>::operator new(size_t n) {     if(n!==sizeof(T)) // 检测请求的尺寸是否正确         throw runtime_error("CachedObj:在 operator new 中错误的对象尺寸");       if(!freeStore) // 如果列表为空     {         T* arr=allo_mem.allocate(chunk); // 分配 chunk 个新 T 类型未构造对象         for(size_t i=0;i!=chunk;++i) // 为新分配内存中的每个对象设置 next 指针             add_to_freelist(arr[i]);           T *p=freeStore;         freeStore=freeStore->CachedObj::next;         return p; // T 的构造函数将构造对象的 T 部分     } }   // 将对象放入自由列表头部 template<typename T> void CachedObj<T>::add_to_freelist(T *p) {     p->CachedObj::next=freeStore; // 下一个可用对象 = 现在的表头     freeStore=p; // 现在的表头 = p }   // operator delete  template<typename T> void CachedObj<T>::operator delete(void *p,size_t n) {     if(p)         add_to_freelist(static_cast<T*>(p)); // 将"删除"的对象添加到列表头部并强制类型转换 }   /////////////////// 继承 CachedObj 的实际使用对象:围棋类 /////////////////////   class Qi:public CachedObj<Qi> { public:     Qi(int kind,int row=0,int col=0,bool d=false):type(kind),x(row),y(col),dead(d){}     void run(int,int); // 走棋     int win(Qi &q);    // 输赢(赢:1 和:0 输:-1)     double get_space(){return space;};// 数目 private:     short  type;      // 棋子类型(黑:0 白:1)     short  x,y;       // 棋子位置     bool   dead;      // 棋子死活     double space;     // 目数 };   void Qi::run(int row,int col) {     if(row<19 && row>=0)          x=row;     else        std::cout<<"位置非法";     if(col<19 && col>=0)         y=col;     else        std::cout<<"位置非法"; }   int Qi::win(Qi &q) {     if(space>q.get_space())         return 1;     else if(space==q.get_space())         return 0;     else        return -1; }     int main() {     Qi black(0,12,12);           system("pause");     return 0; }第14行对虚析构函数进行实现,如virtual ~CachedObj(){};,可以免除链接错误。

delete操作符会调用析构函数,所以有如下几个办法:
1头文件内析构函数可以不写virtual ~CachedObj(); 这样VC++自动会给你生成一个默认析构函数
2把virtual ~CachedObj();实现掉,这行改成virtual ~CachedObj(){}

设为首页 | 联系站长 | 友情链接 | 网站地图 |

copyright©youerw.com 优尔论文网 严禁转载
如果本毕业论文网损害了您的利益或者侵犯了您的权利,请及时联系,我们一定会及时改正。