现在的位置: 首页 > 综合 > 正文

c++ 学习笔记(22)vector模板

2013年08月11日 ⁄ 综合 ⁄ 共 5497字 ⁄ 字号 评论关闭
#include "iostream"
#include "vector"
using namespace std;
//模板要将声明与方法实现在一个文件中(不能分离)http://blog.csdn.net/bichenggui/article/details/4207084
template<typename Object>
//如果其中有非默认的构造函数的话,那其中必须要有默认构造函数,
//两种形式
//1. 
//stock();
//2.
//stock(const char* co = "error", int n = 0, double pr = 0.0)


//总的来书复制构造函数和赋值函数
//存在的问题是可能释放同一个内存两次,因此应该使用new 来进行分配,然后赋值
//但是赋值时,应先释放开始的存在的那个内存,因为此时要重建这个的内容,之前的已经没有用了
class Vector
{
private:
enum{SPARE_CAPACITY = 16};
Object *objects;
int theSize;
int theCapacity;
public: 
explicit Vector(int initSize = 0): theSize(initSize), theCapacity( initSize + SPARE_CAPACITY)
{
objects = new Object[theCapacity];
}
//复制构造函数
Vector(const Vector & rhs):Object(NULL)   //经典
{
operator=(rhs);
}
~Vector();
const Vector & operator=(const Vector & rhs);


void resize(int newSize);
void reserve(int newCapacity);
//common function for LIST and Vector
int size()const; //just index, not change, so add const;
void clear();
bool empty();


void push_back(const Object & x);
void pop_back();
//void insert(int numPosition, size_t n, const Object &x);  //插入时要考虑插入的元素比比之后的元素的个数大还是小,决定插入策略,呵呵呵,这里没有写出哦。
const Object & back() const; //give back the end of the Object;
const Object & front() const; //give the first Object;
/*
//just for double direction List:
void push_front(const Object & x);
void pop_front();
*/
//just for Vector function:
Object & operator[] (int idx);  //give back the index mark object, and don't tack edge detect;
const Object & operator[](int idx) const;
Object & at(int idx);  //give back the index mark object, and tack edge detect;
int capacity()const;  //give the information of the capacity of the container;
//void reserse(int new theCapacity); //apply for new capacity;
typedef Object* iterator;
typedef const Object* const_interator;


iterator begin();
iterator end();
const_interator begin() const;
const_interator end() const;
};


/********************************************************************************/
//析构函数
template<typename Object>
Vector<Object>::~Vector()
{
delete[] objects;
}


template<typename Object>
//遇到的错误:“Vector<Object>::operator =”: 无法将函数定义与现有的声明匹配
//将Vector 改变为:Vector<Object>
const Vector<Object> & Vector<Object>::operator=(const Vector & rhs)
{
if(this = &rhs)
return *this;
delete[] objects;
theSize = rhs.size();
theCapat = rhs.theCapacity;
objects = new Object[capacity()];
int index = 0;
while(index < theSize)
{
objects[index] = rhs.objects[index];
index++;
}


return *this;
}


template<typename Object>
void Vector<Object>::resize(int newSize)
{
if(newSize > theCapacity)
reserve(newSize * 2 + 1);
theSize = newSize;
}


template<typename Object>
void Vector<Object>::reserve(int newCapacity)
{
if(newCapacity < theSize)
return;    //没试过这种形式  //可以理解为退出的意思。后面没有加返回值是因为你的函数类型是void


Object *oldArray = objects;

objects = new Object[newCapacity];
for(int index = 0; index < theSize; index++)
{
objects[index] = oldArray[index];
}
theCapacity = newCapacity;
delete[] oldArray;
}


template<typename Object>
int Vector<Object>::size()const
{
return theSize;
}


template<typename Object>
void Vector<Object>::clear()
{
theSize = 0;
theCapacity = SPARE_CAPACITY;
Object *oldArray = objects;
objects = new Object[theCapacity];


delete[] oldArray;
}


template<typename Object>
bool Vector<Object>::empty()
{
return theSize == 0;
}


template<typename Object>
void Vector<Object>::push_back(const Object & x)
{
if(theSize == theCapacity)
reserve(theCapacity + SPARE_CAPACITY);


objects[theSize] = x;
theSize++;


}

template<typename Object>
void Vector<Object>::pop_back()
{
if(theSize == 0)
return;
theSize--;
}




template<typename Object>
const Object & Vector<Object>::back() const //give back the end of the Object;
{
return objects[theSize-1];
}


template<typename Object>
const Object & Vector<Object>::front() const //give the first Object;
{
return objects[0];
}


template<typename Object>
Object & Vector<Object>::operator[] (int idx)  //give back the index mark object, and don't tack edge detect;
{
return objects[idx];
}


template<typename Object>
const Object & Vector<Object>::operator[](int idx) const
{
return objects[idx];
}


template<typename Object>
Object & Vector<Object>::at(int idx)  //give back the index mark object, and tack edge detect;
{
return objects[idx-1];
}


template<typename Object>
int Vector<Object>::capacity()const  //give the information of the capacity of the container;
{
return theCapacity;
}


template<typename Object>
typename Vector<Object>::iterator Vector<Object>::begin() //返回地址
{
return &objects[0];
}


template<typename Object>
//语法错误 : 缺少“;”(在“Vector<Object>::begin”的前面)
//在之前直接iterator Vector<Object>::end()为这个,后来加上Vector<Object>:: OK了
//原因:前要有typename ,要不然会认为是静态数据成员
typename Vector<Object>::iterator Vector<Object>::end()
{
return &objects[theSize];
}


template<typename Object>
//在这个函数开始之前必须要加typename http://www.cnblogs.com/lidan/archive/2012/02/14/2351811.html
typename Vector<Object>::const_interator Vector<Object>::begin()const
{
return &objects[0];
}
 
template<typename Object>
typename Vector<Object>::const_interator Vector<Object>::end()const
{
return &objects[theSize];
}
/*****************************************************************************************/
int main()
{
Vector<int> vec;
int elem = 10;
for(int i = 0; i < elem; i++)
vec.push_back(i);
int index;
index = vec.at(5);
index = vec.operator [](5);  //都是进行检索,但是结果有区别。
cout << index << endl;
size_t sz = (size_t)(vec.end() - vec.begin());  //判断存储的大小, 灰常给力哦
cout << sz << endl;

int *line = vec.begin();  //首个元素的地址。
cout << line[7] << endl;
cin.get();
cin.get();
return 0;
}

注意:

1. typedef Object* iterator;

    typedef const Object* const_interator;

定义的类型,在后面的函数方法定义时要加上:typename 

typename Vector<Object>::const_interator Vector<Object>::begin()const

是为了说明这个const_interator  是typedef  定义类型的别名,返回值 需要知道他是类型

具体看这

 http://www.cnblogs.com/lidan/archive/2012/02/14/2351811.html;

2.//如果其中有非默认的构造函数的话,那其中必须要有默认构造函数,
//两种形式
//1. 
//stock();
//2.
//stock(const char* co = "error", int n = 0, double pr = 0.0)

//总的来书复制构造函数和赋值函数
//存在的问题是可能释放同一个内存两次,因此应该使用new 来进行分配,然后赋值
//但是赋值时,应先释放开始的存在的那个内存,因为此时要重建这个的内容,之前的已经没有用了

在进行类编写时,一定要注意类的构造函数,复制构造函数,和赋值函数,

3.Object & Vector<Object>::operator[] (int idx)

操作符重载的时候,若是模板怎也要 Vector<Object>在方法中声明啊。

抱歉!评论已关闭.