经过一番研究及测试,通过.需要的朋友可以参考.有以下特点:
完整重载了各必要操作符。
区分不同的类型,进行初始化。
为了验证,特别增加了测试代码。
可以支持多维操作.
完整代码如下:
头文件
#ifndef __GH_SAFE_ARRAY_H__ #define __GH_SAFE_ARRAY_H__ /** * 如何解决memcpy/memset之类的问题? * 二维多维数组怎么支持? */ template <class TYPE> class SafeArray { public: SafeArray(); SafeArray(const int size); SafeArray(const int size, const char* pFile, const char* pFunction, const int nLine); ~SafeArray(); void init(const int size); void init(const int size, const char* pFile, const char* pFunction, const int nLine); int getSize(); int getCurrentOffset(); bool isStart(); bool isEnd(); void resetOffset(); TYPE& operator[](const int i); SafeArray<TYPE>& operator+(const int i); SafeArray<TYPE>& operator-(const int i); TYPE* operator++(const int i); TYPE* operator--(const int i); TYPE* operator+=(const int i); TYPE* operator-=(const int i); //memcpy //memset //copy //clone private: TYPE* m_pData; int m_nSize; int m_nCurrent; char* m_pFile; char* m_pFunction; int m_nLine; }; #endif
实现文件
/** 在C++面向对象程序设计中,有时候需要判断某个对象的类类型,那么可以有下列两种方法: 方法1:采用 typeid()函数进行判断:(缺点:当存在继承,并且子类指针赋值给父类指针时,此时判断的对象类型为父类型,而不是子类类型) 方法2:定义虚函数返回类类型 在运行时类型识别,最简单的办法就是所有的类(父类和子类)实现一个虚方法返回类名字,根据返回类名字再利用typeid()进行判断。如: */ template <typename T> void test(T temp) { //cout<<temp<<endl; } //判断两个类型是否一样 template<typename T1, typename T2> struct is_same_type { operator bool() { return false; } }; template<typename T1> struct is_same_type<T1, T1> { operator bool() { return true; } }; template <typename T> struct is_type_char\ { operator bool() { return false; }}; template <> struct is_type_char<char>\ { operator bool() { return true; }}; template <typename T> struct is_type_int\ { operator bool() { return false; }}; template <> struct is_type_int<int>\ { operator bool() { return true; }}; template <typename T> struct is_base_type { operator bool() { return is_type_char<T>() || is_type_int <T>(); } }; template <class TYPE> SafeArray<TYPE>::SafeArray() { init(0, __FILE__, __FUNCTION__, __LINE__); } template <class TYPE> SafeArray<TYPE>::SafeArray(const int size) { //new (this) SafeArray::SafeArray<TYPE>(m_nSize, __FILE__, __FUNCTION__, __LINE__); init(size, __FILE__, __FUNCTION__, __LINE__); } template <class TYPE> SafeArray<TYPE>::SafeArray(const int size, const char* pFile, const char* pFunction, const int nLine) { init(size, pFile, pFunction, nLine); } template <class TYPE> void SafeArray<TYPE>::init(const int size) { init(size, __FILE__, __FUNCTION__, __LINE__); } template <class TYPE> void SafeArray<TYPE>::init(const int size, const char* pFile, const char* pFunction, const int nLine) { m_nSize = size; m_pData = new TYPE[m_nSize]; m_nCurrent = 0; if (is_base_type<TYPE>()) { memset(m_pData, 0, sizeof(TYPE)*m_nSize); } this->m_pFile = (char*)pFile; this->m_pFunction = (char*)pFunction; this->m_nLine = nLine; //gh_memory_increase(this, m_pFile, m_pFunction, m_nLine, size); } template <class TYPE> SafeArray<TYPE>::~SafeArray() { if (m_pData != NULL) { delete[] (m_pData); m_pData = NULL; m_nSize = 0; } //gh_memory_decrease(this, m_pFile, m_pFunction, m_nLine); } template <class TYPE> bool SafeArray<TYPE>::isStart() { return (m_nCurrent == 0); } template <class TYPE> bool SafeArray<TYPE>::isEnd() { return (m_nCurrent+1 == m_nSize); } template <class TYPE> int SafeArray<TYPE>::getSize() { return m_nSize; } template <class TYPE> int SafeArray<TYPE>::getCurrentOffset() { return m_nCurrent; } template <class TYPE> void SafeArray<TYPE>::resetOffset() { m_nCurrent = 0; } template <class TYPE> TYPE& SafeArray<TYPE>::operator[](const int i) { int pos = (m_nCurrent+i); if (pos >= m_nSize ) { GH_LOG_ERROR("Out of Array Range! %d+%d > %d", m_nCurrent, i, m_nSize); // 返回第一个元素 return m_pData[0]; } return m_pData[pos]; } template <class TYPE> SafeArray<TYPE>& SafeArray<TYPE>::operator+(const int i) { m_nCurrent += i; if (m_nCurrent + i >= m_nSize) { GH_LOG_ERROR("Out of Array Range! %d+%d > %d", (m_nCurrent-i), i, m_nSize); m_nCurrent = 0; } return (*this); } template <class TYPE> SafeArray<TYPE>& SafeArray<TYPE>::operator-(const int i) { m_nCurrent -= i; if (m_nCurrent < 0) { GH_LOG_ERROR("Out of Array Range! %d-%d < 0", (m_nCurrent+i), i); m_nCurrent = 0; } return (*this); } template <class TYPE> TYPE* SafeArray<TYPE>::operator ++ (const int i) { m_nCurrent ++; if (m_nCurrent >= m_nSize) { GH_LOG_ERROR("Out of Array Range! %d++ >= %d", (m_nCurrent-1), m_nSize); m_nCurrent = 0; return m_pData; } return m_pData+m_nCurrent; } template <class TYPE> TYPE* SafeArray<TYPE>::operator -- (const int i) { m_nCurrent --; if (m_nCurrent < 0) { GH_LOG_ERROR("Out of Array Range! %d-1 < 0", (m_nCurrent+1)); m_nCurrent = 0; return m_pData; } return m_pData+m_nCurrent; } template <class TYPE> TYPE* SafeArray<TYPE>::operator+=(const int i) { m_nCurrent += i; if (m_nCurrent >= m_nSize) { GH_LOG_ERROR("Out of Array Range! %d+%d > %d", (m_nCurrent-i), i, m_nSize); m_nCurrent = 0; return m_pData; } return m_pData+m_nCurrent; } template <class TYPE> TYPE* SafeArray<TYPE>::operator-=(const int i) { m_nCurrent -= i; if (m_nCurrent < 0) { GH_LOG_ERROR("Out of Array Range! %d+%d < 0", (m_nCurrent+i), i); m_nCurrent = 0; return m_pData; } return m_pData+m_nCurrent; } #if 1 void testFor1d(SafeArray<int>& test1d) { test1d.resetOffset(); test1d ++; printf("++ %2d\n", test1d[0]); test1d --; printf("-- %2d\n", test1d[0]); test1d += 16; printf("+=16 %2d\n", test1d[0]); test1d -= 16; printf("-=16 %2d\n", test1d[0]); test1d = test1d + 10; printf(" +10 %2d\n", test1d[0]); test1d = test1d - 10; printf(" -10 %2d\n", test1d[0]); } int main(int argc, char** argv) { #if 0 //OK SafeArray<int> test1d(32); for (int i=0; i<test1d.getSize(); i++) { test1d[i] = i; } testFor1d(test1d); #endif #if 0 //OK SafeArray<SafeArray<int>> test2d(32); for (int i=0; i<test2d.getSize(); i++) { //显式初始化 test2d[i].init(32); for (int j=0; j<test2d[i].getSize(); j++) { test2d[i][j] = i*100 + j; } testFor1d(test2d[i]); } #endif #if 1 //OK SafeArray<SafeArray<int>*> test2d2(32); for (int i=0; i<test2d2.getSize(); i++) { //显式新建 test2d2[i] = new SafeArray<int>(32); for (int j=0; j<test2d2[i]->getSize(); j++) { (*test2d2[i])[j] = i*100 + j; } testFor1d(*test2d2[i]); } #endif } #endif