安全访问数组的指针类模板
在用数组作为数据结构存储数据的时候,一不小心就访问越界了,这类错误有时候很不容易发现。为此自己封装一个专门用来访问数组元素的指针类模板。此类模板需要数组的元素类型,起始地址,大小来构造一个安全的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 ;
}
#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 ;
}