已经尝试 定义与实现在一个.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++模板不支持分离式编译,放在一个文件里。