在用數組作為數據結構存儲數據的時候,一不小心就訪問越界了,這類錯誤有時候很不容易發現。為此自己封裝一個專門用來訪問數組元素的指針類模板。此類模板需要數組的元素類型,起始地址,大小來構造一個安全的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;
}