这个类的使用非常有限,不能说是真正的智能数组
对于一般的数据类型还可以,比如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[]