myString操作符重载
写在前面的话:
重载是C++的重要内容,在自定义一个类的时候,需要对类中的方法进行重载,才能方便的实现相应的功能,比如一些运算符,构造,析构函数,一些功能函数等等,而C++语言自带的这些东西只使用于基本数据类型。另外,在自定义类中有指针的属性,注意一下深拷贝和浅拷贝的问题。
下面是自己的实现过程,已测试,可用。
注意:
1、内存泄露问题
2、*a++的含义(想想后置++的重载)
不使用库函数,自定义自己的string类,其中只有一个指针属性(注意重载operator=(),防止浅拷贝问题)
首先,实现myStrlen和myStrcpy这两个常用的函数。
然后,依次实现:
无参构造函数myString():
有参构造函数myString(const char* str):
拷贝构造函数myString(const myString& copyObj):
析构函数~myString(void):
int myStrlen(const char* str):
char* myStrcpy(char* des, const char* src):
operator=()(const myString& obj):
const char* myAppend(const char* str):
const char* toLow():
int myCompareCaseInsensitive(const char* str):
1.辅助函数
int myString::myStrlen(const char* str) { assert(NULL != str); const char* end= str; while ('\0' != *end++); return end - str; } char* myString::myStrcpy(char* des, const char* src) { assert(NULL != des && NULL != src); char* ret = des; const char* retSrc = src; while ((*ret++ = *retSrc++) != '\0'); return des; }
2.无参构造函数,有参构造函数,拷贝构造函数,目标对象尚未存在,直接申请空间,赋值即可。
myString::myString() { myData = new char[1]; if (NULL != myData) myStrcpy(myData, ""); } myString::myString(const char* str ) { if (NULL == str) //对于空串儿,将myData初始化为'\0' { myData = new char[1]; if (NULL != myData) myStrcpy(myData, ""); } else if (NULL != str) { myData = new char[myStrlen(str) + 1]; if (NULL != myData) myStrcpy(myData, str); } } myString::myString(const myString& copyObj) //const(只读) 引用(若用元素会死循环) { myData = new char[myStrlen(copyObj.myData) + 1]; if (NULL != myData) myStrcpy(myData, copyObj.myData); } myString::~myString(void) { if (NULL != myData) { delete []myData; myData = NULL; } }
3. operator=(const myString& obj)
myString& myString::operator =(const myString& obj) { if (this == &obj) //自身返回 1.*this和obj是自定义数据类型,没有重载==会报错; return *this; //2.this和&obj是指针,可以使用==; //3.不使用myData==obj.myData是因为自定义类中不一定只有myData一个属性(比如,加一个len) if (NULL != myData) { delete[] myData; myData = NULL; } myData = new char[myStrlen(obj.myData) + 1]; if (NULL != myData) myStrcpy(myData, obj.myData); return *this; }
4. const char* myAppend(const char* str)
const char* myString::myAppend(const char* str) { assert(NULL != myData && NULL != str); char* temp_myData = myData; char*head_myData = myData; const char* temp_str = str; int n = 0; n = myStrlen(myData) + myStrlen(str) + 1; char* ret = new char[n + 1]; myData = ret; while ((*ret++=*temp_myData++) != '\0') ; ret--; while ((*ret++ = *temp_str++) != '\0'); delete[] head_myData; //释放原有内存 head_myData = NULL; return myData; }
5.转换大小写
const char* myString::toLow() { if (NULL == myData) return NULL; char* ret = myData; while ('\0' != *ret) { if (*ret >= 'A' && *ret <= 'Z') *ret += 32; ++ret; } return myData; }
6. 比较函数,不区分大小写
int myString::myCompareCaseInsensitive(const char* str) { unsigned char* src = (unsigned char*)str; //强制类型转换 int ret = 0; char* temData = myData; while ('\0' != *src && '\0' != *temData && (0 == (*temData - *src) || 32 == (*temData - *src) || 32 == (*src - *temData))) { ++temData; ++src; } ret = *temData - *src; if (0 == ret || 32 == ret || -32 == ret || ('\0' == *src && '\0' == *temData)) ret = 0; if ((ret > 0 && ret != 32) || ('\0' == *src && '\0' != *temData)) { ret = 1; } if ((ret < 0 && ret != -32) || ('\0' == *temData && '\0' != *src)) { ret = -1; } return ret; }