C++Array类模板
函数模板和类模板都属于泛型技术,利用函数模板和类模板来创建一个具有通用功能的函数和类,以支持多种不同的形参,从而进一步简化重载函数的函数体设计。
声明方法:template<typename/class 标识符(T)>
函数声明(通用形参使用标识符(T)代替)
//Array.h #ifndef ARRAY_H #define ARRAY_H #include<cassert> template<class T> class Array { private: T* m_list; int m_size; public: //构造函数 Array(int sz=50); //拷贝构造函数 Array(const Array<T>&a); //析构函数 ~Array(); //重载“=”可以让数组对象整体赋值 Array<T>& operator=(const Array<T>& rhs); //重载“[]”使Array对象可以索引指定位置数据 T& operator[](int i); //此处必须返回引用,若返回值,则无法直接进行运算,变量使用完毕后便被销毁 //“[]”针对const的重载 const T& operator[](int i) const; //重载T*类型转换 operator T*(); //“T*”针对const的重载 operator const T*() const; //获取数组大小 int getSize() const; //改变数组大小 void resize(int sz); }; template<class T> Array<T>::Array(int sz) { assert(sz); m_size=sz; m_list=new T[m_size]; } template<class T> Array<T>::Array(const Array<T>& a) { //浅复制 m_size=a.m_size; m_list=a.m_list; //深复制 m_size=a.m_size; m_list=new T[m_size]; for (int i = 0; i < m_size; i++) { m_list[i]=a.m_list[i]; } } template<class T> Array<T>::~Array() { delete[] m_list; } template<class T> Array<T>& Array<T>::operator=(const Array<T>& chs) { if (&chs!=this) { if (chs.m_size!=this.m_size) { delete[] m_list; m_size=chs.m_size; m_list=new T[m_size]; } for (int i = 0; i < m_size; i++) { this.m_list[i]=chs.m_list[i]; } } return *this; } template<class T> //此处引用有两点:1.不能返回临时变量,否则引用无值索引;2.此处必须为引用,若为值类型,操作数必须为左值。 T& Array<T>::operator[](int i) { assert(i>=0&&i<m_size); //有待测试 /*T temp=m_list[i]; return temp;*/ return m_list[i]; } template<class T> Array<T>::operator T*() { return m_list; } template<class T> int Array<T>::getSize() const { return m_size; } template<class T> void Array<T>::resize(int sz) { assert(sz>=0); if (sz==m_size) { return; } else { T* Newlist=new T[sz]; int n=(m_size<sz)?m_size:sz; for (int i = 0; i < n; i++) { Newlist[i]=m_list[i]; } delete[] m_list; m_list=Newlist; m_size=sz; delete[] Newlist; } } #endif
在本次我编写的Array类模板中,可以看出类模板的本质还是函数模板构成的。同时,在此次编写类模板的过程中,深刻地体会了C++的三个知识点。
分别是拷贝构造函数的深复制与浅复制,成员函数与非成员函数运算符重载,返回值与返回引用的区别。接下来,将详细说这三个知识点。
- 拷贝构造函数的深复制与浅复制:拷贝构造函数,是以对象的引用作为形参,并用const常量约束。若对象为头指针和线性空间存储数据的形式,浅复制,则是只复制了头指针和空间大小,而未真正意义上实现线性空间的数据复制;而深复制,则将被复制对象的线性空间所有的数据依次赋予对象。
- 成员函数运算符重载和非成员函数运算符重载的区别:成员函数在二目运算符中,只需要一个形参,另外一个为本对象的this指针;而非成员函数在二目运算符中,则需要两个形参。
- 返回值与返回引用的区别:返回值,即生成了return变量的拷贝,在使用后,临时变量就将被销毁。因此,返回值后不能做左值运算。返回引用,即生成对return变量的别名,可对此变量操作,进行左值运算。但返回引用,返回的不能是临时变量,必须是类成员变量或局部静态变量或传入的引用形参。