在用数组作为数据结构存储数据的时候,一不小心就访问越界了,这类错误有时候很不容易发现。为此自己封装一个专门用来访问数组元素的指针类模板。此类模板需要数组的元素类型,起始地址,大小来构造一个安全的Ptr2T指针对象,此对象访问数组的方法不但与普通的指针相同,同时还增加了越界的安全检查。
#include <iostream>
#include <stdexcept>
using namespace std;
template<typename T>
class Ptr2T {
public:
//构造函数,形参为数组起始地址和大小
Ptr2T(T *p, int size)
: m_p(p), m_array(p), m_size(size) { };
Ptr2T& operator++(); //前缀++
const Ptr2T operator++(int); //后缀++
Ptr2T& operator--(); //前缀--
const Ptr2T operator--(int); //后缀--
Ptr2T& operator+=(int n);
Ptr2T& operator -=(int n);
//安全的数组元素访问操作
T& operator*() const;
private:
T *m_p; //访问数组的指针
T *m_array; //保存数组的起始地址
int m_size; //保存数组的大小
};
template<typename T>
inline Ptr2T<T>& Ptr2T<T>::operator++()
{
m_p += 1;
return *this;
}
template<typename T>
inline const Ptr2T<T> Ptr2T<T>::operator++(int)
{
Ptr2T current = *this;
++(*this); //用重载的前缀++来实现
return current;
}
template<typename T>
inline Ptr2T<T>& Ptr2T<T>::operator--()
{
m_p -= 1;
return *this;
}
template<typename T>
inline const Ptr2T<T> Ptr2T<T>::operator--(int)
{
Ptr2T current = *this;
--(*this); //用重载的前缀--来实现
return current;
}
template<typename T>
inline T& Ptr2T<T>::operator*() const
{
if (m_p < m_array || m_p > m_array + m_size - 1) { //越界检查
throw out_of_range("out of range");
}
return *m_p;
}
template<typename T>
inline Ptr2T<T>& Ptr2T<T>::operator+=(int n)
{
m_p += n;
return *this;
}
template<typename T>
inline Ptr2T<T>& Ptr2T<T>::operator-=(int n)
{
m_p -= n;
return *this;
}
template<typename T>
Ptr2T<T> operator+(const Ptr2T<T> &p, const int n)
{
return Ptr2T<T>(p) += n; //用重载的+=来实现
}
template<typename T>
Ptr2T<T> operator+(const int n, const Ptr2T<T> &p)
{
return p + n;
}
template<typename T>
Ptr2T<T> operator-(const Ptr2T<T> &p, const int n)
{
return Ptr2T<T>(p) -= n; //用重载的-=来实现
}
//使用方法
int main(void)
{
char a[5] = {'a', 'b', 'c', 'd', 'e'};
int b[5] = {1, 2, 3, 4, 5};
Ptr2T<char> pc(a, 5);
Ptr2T<int> pi(b, 5);
cout << *pc++ << endl;
pi--;
pi += 2;
cout << *(pi - 1) << endl;
*++pi = 100;
cout << *pi << endl;
return 0;
}