数据结构与算法Cpp-01

动态数组、异常类和操作符重载等

1 相关概念

  • 动态数组:在数组中插入元素时,如果数组容量已满,则进行扩容(类的void extend()私有函数),扩为原来的两倍。
  • 自己定义异常类:创建多个构造函数。在测试案例中,利用try…catch捕获异常。
  • 构造函数、析构函数和拷贝构造函数
  • 操作符[]、<<(不能重载到成员函数中)重载。
    目前案例比较简单,插入和删除都在数组的尾部进行。如果在前段和中部插入和删除就要涉及其他元素的移动,但也比较容易实现(可利用copy函数实现)。

2 相应的代码

  • 异常类代码
// "OutofRange.h"
#ifndef _OUTOFRANGE_H
#define _OUTOFRANGE_H
#include<iostream>

class OutofRange
{
public:
	OutofRange() :err_t(1) {}
	OutofRange(int _arrcapacity,int _arrsize,int _arrindex) :arrcapacity(_arrcapacity),
		arrsize(_arrsize),arrindex(_arrindex),err_t(2){}
	//~OutofRange() {}  //没有指针,不用自己定义析构函数。

	//方法
	void what() const;

private:
	int err_t;   //错误类型
	int arrindex;  //元素所在的索引
	int arrsize;
	int arrcapacity;   //数组的容量

};

void OutofRange::what()const
{
	if (err_t == 1)
	{
		std::cout << "当前数组为空!";
	}
	else if (err_t == 2)
	{
		std::cout << "当前元素所在的索引:" << arrindex
			<< ",当前数组元素的个数: " << arrsize
			<< ",当前数组的容量:" << arrcapacity;
	}
	else
	{
		std::cout << "其他未知错误。";
	}
}
#endif // !_OUTOFRANGE_H
  • 动态数组代码
#ifndef ARRRAY_H
#define ARRAY_H
#include"OutofRange.h"
#include<iostream>

template<class T>
class Array
{
	template<class T>
	friend std::ostream& operator<<(std::ostream&, const Array<T>&);
public:
	Array(int initalcapacity = 10);
	Array(const Array<T>&);
	~Array() { delete[]element; }

	//ADT方法
	bool empty() { return arrsize == 0; }
	int getsize()const { return arrsize; }
	void push(const T &theElement);
	void pop();
	T& operator[](int i) const; //重载[]操作符,获取数组元素。
	void clear();


private:
	T* element;
	int arrsize;
	int arrcapacity ;

	void extend();
};

template<class T>
void Array<T>::clear()
{
	for (int i = arrsize - 1; i >= 0; i--)
	{
		element[i].~T();
		--arrsize;
	}

	;
}

//拷贝构造函数
template<class T>
Array<T>::Array(const Array<T>& arr)
{
	arrsize = arr.arrsize;
	arrcapacity = arr.arrcapacity;
	element = new T[arrcapacity];
	std::copy(arr.element, arr.element + arrsize, element);
}



//构造函数
template<class T>
Array<T>::Array(int initalcapacity)
{
	arrcapacity = initalcapacity;
	arrsize = 0;
	element = new T[arrcapacity];
}


//操作符<<重载
template<class T>
inline
std::ostream& operator<<(std::ostream& out, const Array<T>& arr)
{
	for (int i=0;i<arr.arrsize;i++)
		out << *(arr.element+i) << " ";
	out << std::endl;
	return out;
}

//操作符[]重载
template<class T>
T& Array<T>::operator[](int i) const
{
	if (i > arrsize - 1 || i < 0) throw OutofRange(arrcapacity, arrsize, i);

	return *(element + i);
}


//尾端删除一个元素
template<class T>
void Array<T>::pop()
{
	if (arrsize == 0) throw OutofRange();
	element[arrsize - 1].~T();
	--arrsize;
}


//扩容为原来的两倍
template<class T>
void Array<T>::extend()
{
	T* newelement = new T[arrcapacity * 2];
	std::copy(element, element + arrsize, newelement);
	delete[]element;

	element = newelement;
	arrcapacity *= 2;
}
//在数组尾端插入数据
template<class T>
void Array<T>::push(const T &theElement)
{
	if (arrsize >= arrcapacity) extend();
	element[arrsize] = theElement;
	++arrsize;
}
#endif // !ARRRAY_H
  • 测试代码
#include<iostream>
#include"Array.h"
using namespace std;
int main()
{
	try {
		Array<int> arr;
		for (int i = 0; i < 15; i++)
			arr.push(i);
		cout << arr << endl;

		arr.pop();
		cout << arr << endl;

		cout << "*********测试拷贝构造函数***********" << endl;
		Array<int> arr1(arr);
		cout << arr1 << endl;

		cout << "*****测试清空数组*******************" << endl;
		arr.clear();
		
		if (arr.empty())
		{
			cout << "数组是空的" << endl;
		}
		cout << "目前数组中的元素"<<arr.getsize() << endl;		
	}
	catch (OutofRange &e)
	{
		e.what();
	}
}

测试案例结果
该例子较为简单,但麻雀虽小,五脏俱全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值