关闭

C++模板实现智能数组类

3276人阅读 评论(1) 收藏 举报

这个类的使用非常有限,不能说是真正的智能数组

对于一般的数据类型还可以,比如int /float/char等

但是,string类这样的类类型好像不是很好

但是一些基础的东西却是学习的重点

头文件MyArray.h:

#pragma once
#include <iostream>
using namespace std;
template<class T,int N=5>//定义一个类似数组的模板类(智能数组)
class CMyArray
{
public:
	CMyArray(const T& v);
	~CMyArray(void);
	void Show()const;
	int GetLength()const;//获取对象当前元素数目
	int GetTotalSize()const;//获取对象当前申请的总内存
	void ShowSize()const;//显示当前对象的元素个数和总内存数
	T RemoveAt(const int& index);//删除指定位置的元素(索引从0开始),返回删除的元素
	bool RemoveAll();//删除所有元素
	bool IsEmpty()const;//判断当前容器是否为空
	T& operator [](int i);
	void Pop(const T& t);//尾部加入一个元素
	T Push();//尾部删除一个元素,返回该元素
	friend ostream& operator<<(ostream& os,const CMyArray& a)
	{
		a.Show();
		return os;
	}
private:
	T* temp;
	int m_nTotalSize;//当前的总内存数目
	int m_nValideSize;//当前的实际元素个数
};
template<class T,int N>
CMyArray<T,N>::CMyArray(const T& v):temp(NULL)
{
	temp=new T[N];
	m_nTotalSize=m_nValideSize=N;
	for(int i=0;i<N;i++)
		temp[i]=v;
}
template<class T,int N>
CMyArray<T,N>::~CMyArray(void)
{
	if(temp!=NULL)
	{

		delete[] temp;
		temp=NULL;
	}
}
template<class T,int N>
void CMyArray<T,N>::Show()const
{
	if(m_nValideSize==0)
	{
		cout<<"当前对象为空,无法输出"<<endl;
		return;
	}
	cout<<"依次输出当前"<<m_nValideSize<<"个元素"<<endl;
	for(int i=0;i<m_nValideSize;i++)
    	cout<<temp[i]<<"   ";
	cout<<endl;
}
template<class T,int N>
T& CMyArray<T,N>::operator [](int i)
{
	if(i<0||i>N-1)
	{
		cout<<"数组越界,返回第一个元素"<<endl;
		i=0;
	}
	return temp[i];
}
template<class T,int N>
int CMyArray<T,N>::GetLength()const
{
	return m_nValideSize;

}
template<class T,int N>
void CMyArray<T,N>::Pop(const T& t)
{
	if(m_nValideSize<m_nTotalSize)//还有空闲内存
	{
		temp[m_nValideSize]=t;
		m_nValideSize++;
	}
	else//内存用完,继续申请
	{
		//先保存当前数据到临时指针中
		T* data=new T[m_nTotalSize];
		for(int i=0;i<m_nTotalSize;i++)
		{
			data[i]=temp[i];
		}
		delete[] temp;//释放内存
		temp=NULL;//避免产生野指针
		m_nTotalSize*=2;//扩容一倍
		temp=new T[m_nTotalSize];
		for(int i=0;i<m_nValideSize;i++)
		{
			temp[i]=data[i];//复制数据到原始指针中
		}
		delete[] data;//释放内存
		data=NULL;
		temp[m_nValideSize]=t;
		m_nValideSize++;

	}
}
template<class T,int N>
int CMyArray<T,N>::GetTotalSize()const
{
	return m_nTotalSize;
}
template<class T,int N>
T CMyArray<T,N>::Push()
{
	T t;
	if(m_nValideSize==0)
	{
		cout<<"容器已空!"<<endl;
		t=(T)NULL;
		return t;
	}
	t=temp[m_nValideSize];
	m_nValideSize--;
	if((m_nValideSize%N)==0)//刚好多出一个元素,为了节省内存,释放掉一个N的内存
	{
		T* data=new T[m_nValideSize];
		for(int i=0;i<m_nValideSize;i++)
			data[i]=temp[i];
		delete[] temp;//释放内存
		temp=NULL;
		temp=new T[m_nValideSize];//申请内存
		m_nTotalSize=m_nValideSize;
		for(int i=0;i<m_nValideSize;i++)
			temp[i]=data[i];
		delete[] data;
		data=NULL;
	}
	return t;
}
template<class T,int N>
void CMyArray<T,N>::ShowSize()const
{

	cout<<"当前对象中元素数目为:"<<m_nValideSize<<endl;
	cout<<"总内存为:"<<m_nTotalSize<<endl;
}
template<class T,int N>
T CMyArray<T,N>::RemoveAt(const int& index)
{
	if(m_nValideSize==0)
	{
		cout<<"容器已经为空"<<endl;
		return (T)NULL;
	}
	if(index<0||index>m_nValideSize-1)//数组越界
	{
		cout<<"数组越界,无法完成删除操作"<<endl;
		return (T)NULL;
	}
	T ret=temp[index];
	m_nValideSize--;
	T* data=new T[m_nValideSize];
	for(int i=0;i<index;i++)
		data[i]=temp[i];
	for(int i=index;i<m_nValideSize;i++)
		data[i]=temp[i+1];
	delete[] temp;
	temp=NULL;
	temp=new T[m_nValideSize];
	for(int i=0;i<m_nValideSize;i++)
		temp[i]=data[i];
	delete[] data;
	data=NULL;
	return ret;

}
template<class T,int N>
bool CMyArray<T,N>::RemoveAll()
{
	if(m_nValideSize==0)
	{
		cout<<"容器已经为空"<<endl;
		return flase;
	}
	delete[] temp;
	temp=NULL;
	m_nValideSize=m_nTotalSize=0;
	return true;
}
template<class T,int N>
bool CMyArray<T,N>::IsEmpty()const
{
	if(m_nValideSize==0)
		return true;
	return false;
}

主函数测试功能:

// C++模板类.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include "MyArray.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
/*	CMyArray<int,7> a(3);
	a.Show();
	a.Pop(5);
	a.Show();
	int len=a.GetLength();
	int size=a.GetTotalSize();
	cout<<len<<endl<<size<<endl;*/
/*	CMyArray<int,7> a(5);
	a.Show();
	a.Pop(6);
	a.ShowSize();
	a.Push();
	a.ShowSize();*/
/*	CMyArray<int,1> a(0);
	a.Show();
	a.Push();
	a.Show();
	CMyArray<float,1> str(0.001);
	str.Show();
	str.Push();
	str.Show();*/
	CMyArray<int> a(0);
	a[0]=5;
	a[1]=3;
	a.Show();
	a.RemoveAt(0);
	a.Show();
	a.IsEmpty();
	cout<<a<<endl;
	CMyArray<char> c('a');
	c.Show();
	return 0;
} 

指针是C++中的一把双刃剑,用得好可以事半功倍

同样,稍不注意就会造成内存泄露,产生野指针。

使用指针特别要注意:

有new 则有delete

new【】则对应则delete[]

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:635489次
    • 积分:6570
    • 等级:
    • 排名:第3860名
    • 原创:104篇
    • 转载:53篇
    • 译文:0篇
    • 评论:178条
    打赏
    微信扫码
    最新评论