设为首页 加入收藏

TOP

C++模板函数声明定义分离编译错误详解(一)
2014-11-24 03:11:45 来源: 作者: 【 】 浏览:5
Tags:模板 函数 声明 定义 分离 编译 错误 详解

今天看到accelerated c++上有个简单的vector容器的实现Vec,就再vs2008上编译了下:


///// Vec.h



#ifndef GUARD_VEC_H


#define GUARD_VEC_H



#include


#include


#include


//#include



template


class Vec


{


public:


typedef T* iterator;


typedef const T* const_iterator;


typedef size_t size_type;


typedef T value_type;


typedef T& reference;


typedef const T& const_reference;



Vec() {create();} //默认的构造函数


explicit Vec(size_type n,const T& t=t()) {create(n,t);} //单参数或者两个参数构造函数


Vec(const Vec& v) {create(v.begin(),v.end());} //拷贝构造函数


Vec& operator=(const Vec&); //赋值构造函数


~Vec() {uncreate();} //析构函数



size_type size() { return avail-data; } //定义类的大小,ptrdiff_t自动转化成size_t


void push_back(const T& t)


{


if (avail==limit)


{


grow();


}


unchecked_append(t);


}


//重载【】


T& operator[] (size_type i) { return data[i]; }


const T& operator[] (size_type i) const { return data[i]; }


//定义begin和end,都有两个版本


iterator begin() {return data;}


const_iterator begin() const {return data;}


iterator end() {return avail;}


const_iterator end() const {return avail;}


protected:


private:


iterator data; //Vec中得初始值


iterator avail; //Vec中得结束值


iterator limit; //Vec中空间分配的结束值


std::allocator alloc; //注意此处std


//创造函数,负责内存管理


void create();


void create(size_type,const T&);


void create(const_iterator,const_iterator);


//销毁元素,返回内存


void uncreate();


//支持push_back函数


void grow();


void unchecked_append(const T&);


};



#endif



//// Vec.cpp



#include


#include "Vec.h"


//#pragma comment(lib,"ws2_32.lib")



using namespace std;



//拷贝构造函数


template


Vec& Vec::operator=(const Vec& v)


{


if (&v!=this) //检查是否为自我赋值,很重要,必须有


{


uncreate(); //清空左值的元素


create(v.begin(),v.end()); //拷贝元素到左值


}


return *this;


}





//push_back函数中内存增长策略函数


template


void Vec::grow()


{


size_type new_size=max(2*(limit-data),ptrdiff_t(1)); //防止刚开始内存空间为0的情况


iterator new_data=alloc.allocate(new_size); //返回首地址


//把前两个参数指定的元素复制给第三个参数表示的目标序列,返回末尾元素的下一个迭代器


iterator new_avail=uninitialized_copy(data,avail,new_data);


uncreate(); //释放原先的空间



data=new_data;


avail=new_avail;


limit=data+new_size;


}



//向申请的内存中添加元素


template


void Vec::unchecked_append(const T& val)


{


//在未初始化的空间构建一个对象,参数1插入对象的位置指针,参数2需要添加的对象


alloc.construct(avail++,val);


}




//申请内存的函数create


template


void Vec::create()


{


data=avail=limit=0;


}


template


void Vec::create(size_type n,const T& val)


{


data=alloc.allocate(n); //申请内存空间,但是不初始化


limit=avail=data+n;


uninitialized_fill(data,limit,val); //进行初始化


}


template


void Vec::create(const_iterator i,const_iterator j)


{


data=alloc.allocate(j-i);


limit=avail=uninitialized_copy(i,j,data);


}



//回收内存


template


void Vec::uncreate()


{


if (data) //如果data是0,我们不需要做什么工作


{


iterator it=avail;


while (it!=data)


alloc.destroy(--it); //销毁没个元素,为了与delete行为一致,采用从后向前遍历


alloc.deallocate(data,limit-data); //内存释放,函数需要一个非零指针


//因此,检测data是否为零


}


data=limit=avail=0;


}



//// 测试的main函数



#include


#include "Vec.h"


using namespace std;


int main()


{


Vec a;


Vec b;


a.push_back(12);


b=a;


return 0;


}

结果编译后出现下面错误:

1>------ 已启动生成: 项目: Accelerated, 配置: Debug Win32 ------
1>正在编译...
1>Vec.cpp
1>Vec_example.cpp
1>正在生成代码...
1>正在链接...
1>Vec_example.obj : error LNK2001: 无法解析的外部符号 "public: class Vec & __thiscall Vec::operator=(class Vec const &)" ( 4 $Vec@H@@

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇autoconf添加gcc调试选项 下一篇Python爬虫多线程抓取代理服务器

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)
·索引堆及其优化 - 菜 (2025-12-24 20:18:50)
·Shell 中各种括号的 (2025-12-24 19:50:39)
·Shell 变量 - 菜鸟教 (2025-12-24 19:50:37)