C++中的数组类模板有关笔记

之前说过C++中的类模板可以容纳任何类型的数据,那能否建立一个通用的组(类)使得也能够容纳任何类型的数组?

.直接访问的线性群体——数组类
.静态数组是具有固定元素个数的群体,其中的元素可以通过下标直接访问。
.缺点:大小正在编译时就已经确定,在运行时无法修改

.动态数组有一系列位置连续的,任意数量相同类型的元素组成
.优点:其元素个数可以在程序运行时改变

.动态数组类模板程序

#ifndef ARRAY_H
#define ARRAY_H
#include <cassert>//提供宏assert的定义。可以在程序中关键的地方使用这个宏来进行断言。如果一处断言被证明非真,我们希望程序在标准错误流输出一条适当的提示信息,并且使执行异常终止。

template<class T>//数组类模板定义
class Array
{
    
    
public:
	Array(int sz = 50);      //构造函数
	Array(const Array<T>& a);//赋值构造函数
	~Array();                //析构函数

	//重载“=”
	//如果一个函数的返回值是一个对象的值,就是右值,不能成为左值
	//如果返回值为引用。由于引用是对象的别名,通过引用可以改变对象的值,因此是左值(我们希望能修改运算后的数组)
	Array<T>& operator =(const Array<T>& rhs);
	//重载“[]”
	T& operator [](int i);
	//重载“[]”常函数
	const T& operator [](int i)const;
	//重载到T*类型的转换
	operator T* ();
	operator const T* ()const;

	int getSize()const;     //取数组的大小
	void resize(int sz);    //修改数组的大小
private:
	T* list;                 //用于存放动态分配的数组的内存首地址
	int size;                //数组大小(元素个数)
};

//构造函数
template <class T>
Array<T>::Array(int sz)
{
    
    
	assert(sz >= 0);   //sz为数组大小,应当为非负数
	size = sz;         //将元素个数赋值给变量size
	list = new T[size];//动态分配size个T类型的元素空间
}

//复制构造函数
template <class T>
Array<T>::Array(const Array<T>& a)
{
    
    
	//获取对象x的大小size,并赋值给当前对象的成员
	size = a.size;
	//动态分配n个T类型的元素空间
	list = new T[size];
	//从对象x复制元素到本对象
	for (int i=0;i<size;i++)
	{
    
    
		list[i] = a.list[i];
	}
}

//析构函数
template <class T>
Array<T>::~Array()
{
    
    
	delete[] list;//new过申请的空间要靠delete释放
}

//重载“=”,将对象rhs赋值给本对象,实现对象之间的主体赋值
template <class T>
Array<T>& Array<T>::operator=(const Array<T>& rhs)
{
    
    
	if(&rhs!=this)
	{
    
    
		//如果本对象中的数组大小与rhs的不同,则删除数组原有内存,然后重新分配
		if(size!=rhs.size)
		{
    
    
			delete[] list;     //删除数组原有的内存
			size = rhs.size;   //设置本对象的大小
			list = new T[size];//重新分配size个T类型元素的内存
		}
		//从对象x复制数组元素到本对象
		for(int i=0;i<size;i++)
		{
    
    
			list[i] = rhs.list[i];
		}
	}
	//返回当前对象的引用
	return *this;
}

//重载下标运算符,实现与普通数组一样通过下标访问元素,并具有越界检查功能
template <class T>
T& Array<T>::operator[](int i)
{
    
    
	assert(n >= 0 && n < size);//检查下标是否越界
	return list[n];            //返回下标为n的数组元素
}

template <class T>
const T& Array<T>::operator[](int i)const
{
    
    
	assert(n >= 0 && n < size);//检查下标是否越界
	return list[n];            //返回下标为n的数组元素
}

//重载指针转换运算符,将Array类的对象名转换为T类型的指针
//这样就可以接收赋值了
template <class T>
Array<T>::operator T*()
{
    
    
	return list;//返回当前对象中私有数组的首地址
}

//取当前数组的大小
template <class T>
int Array<T>::getSize() const
{
    
    
	return size;
}

//将数组大小修改为sz
//基于底层基于数组调整大小,这个时间空间开销很高
template <class T>
void Array<T>::resize(int sz)
{
    
    
	//检查sz是否为非负
	assert(sz >= 0);
	//如果指定的大小与原有大小一样,则说明也不做
	if(sz==size)
	{
    
    
		return;
	}
	T* newList = new T[sz];         //申请新的数组内存
	int n = (sz < size) ? sz : size;//将sz与size中较小的一个赋值给n

	//将原有数组中前n个元素复制到新数组中
	for(int i=0;i<n;i++)
	{
    
    
		newList[i] = list[i];
	}

	delete[] list; //删除原数组
	list = newList;//使list指向新的数组
	size = sz;     //更新size
}
#endif  //ARRAY_H

应用例子:

int main()
{
    
    
	//用来存放质数的数组,初始状态有10个元素
	Array<int> a(10);
	int n, count = 0;
	cout << "Enter a value >= 2 as upper limit for prime numbers:";
	cin >> n;

	for(int i=2;i<n;i++)
	{
    
    
		//检查i是否能被比它小的质数整除
		bool isPrime = true;
		for(int j=0;j<count;j++)
		{
    
    
			//若i被a[j]整除,说明i不是质数
			if(i%a[j]==0)
			{
    
    
				isPrime = false;
				break;;
			}
			if(isPrime)
			{
    
    
				if(count==a.getSize())
				{
    
    
					a.resize((count * 2));
				}
				a[count++] = i;
			}
		}
	}
	for(int i=0;i<count;i++)
	{
    
    
		cout << setw(8) << a[i];
	}
	cout << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43530773/article/details/114286501