已经尝试 定义与实现在一个.h文件,也尝试了分开写同时include .h\.cpp 但是都有错误
代码如下
代码如下
//--collection,h #ifndef collection #define collection #include <list> #include <cstdlib> #include <typeinfo> using namespace std; template<class T> class GCInfo { public: T*memptr; unsigned int times; GCInfo() { memptr = NULL; times = 0; } GCInfo(T*ptr) { memptr = ptr; times = 0; } ~GCInfo(){} }; template<class T,int size=0> class GCptr { public: GCptr() { addr = NULL; } GCptr(T*ptr) { addr = ptr; } ~GCptr() {}; typename list<GCInfo<T>>::iterator GCptr<T, size>::findPtrInfo(T*ptr); T* operator=(T*ptr); GCptr<T, size>& operator=(GCptr<T, size>& gcptr); void collect(); T& operator*(); T*operator->(); static list < GCInfo<T>> gclist; T*addr; }; #endif //--collection.cpp #include "collection.h" //找到指针在相应类型链表的位置返回迭代器 template<class T, int size> typename list<GCInfo<T>>::iterator GCptr<T, size>::findPtrInfo(T*ptr) { list <GCInfo<T>>::iterator p; for (p = gclist.begin(); p != gclist.end(); ++p) if (p->memptr == ptr)return p; return p; } //重载赋左值 template<class T, int size> T*GCptr<T, size>::operator=(T*ptr) { list<GCInfo<T>>::iterator p; p = findPtrInfo(addr); //该指针失去对该内存全部权计数减一 p->times--; p = findPtrInfo(ptr); if (p == gclist.end()) { GCInfo<T> new_gcinfo(ptr); new_gcinfo.times++; gclist.push_front(new_gcinfo); } else { p->memptr = ptr; p->times++; } return ptr; } //重载赋右值 template<class T, int size> GCptr<T, size>& GCptr<T, size>::operator=(GCptr<T, size>& gcptr) { list<GCInfo<T>>::iterator p; p = findPtrInfo(addr); p->times++; gcptr.addr = addr; } //重载解引用操作符 template<class T, int size> T& GCptr<T, size>::operator*() { return *addr; } //重载箭头 template<class T, int size> T* GCptr<T, size>::operator->() { return addr; } //收集无用内存 template<class T, int size> void GCptr<T, size>::collect() { list<GCInfo<T>>::iterator p; for (p = gclist.begin(); p != gclist.end(); p++) { if (p->times == 0) gclist.erase(p); } } //--main.cpp #include "collection.h" #include "collection.cpp" class a { int b; }; int main() { a c; a e; GCptr<a, 0> f ; f = &c; GCptr<a, 0> g = f; return 0; }
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2001 无法解析的外部符号 “public: static class std::list<class GCInfo<class a>,class std::allocator<class GCInfo<class a> > > GCptr<class a,0>::gclist” (?gclist@?$GCptr@Va@@$0A@@@2V?$list@V?$GCInfo@Va@@@@V?$allocator@V?$GCInfo@Va@@@@@std@@@std@@A) cpp_collection E:\vs 项目\cpp_collection\cpp_collection\main.obj 1
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK1120 1 个无法解析的外部命令 cpp_collection E:\vs 项目\cpp_collection\Debug\cpp_collection.exe 1
解决方案
20
模板不要分开写,除非是模板特化….写在头文件里面就行
20
模板定义很特殊。由template<…> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义
10
c++模板不支持分离式编译,放在一个文件里。