// // Created by lenfrex on 2022/4/4. // #include #include #include "CString.h" /* * 按照给定大小来初始化字符串数据 */ CString::CString(int length) { data = new char[length](); } CString::~CString() { delete[] data; data = nullptr; } /* * 不设定初始化大小就默认512个字符来初始化 */ CString::CString() : CString(512) {} /* * 重载等号。借鉴了Java中String类的equal()方法的实现思路。 * 首先判断data是否为nullptr,同为null则true,否则就是false * 再比较两字符串长度,如果长度不一样不用说,直接返回false; * 相同的话再比较两字符串数据指针指向地址是否一样,一样就代表指向的是同一块内存,直接返回true * 两者都不同才进行逐字比较 */ bool CString::operator==(const CString &source) const { // 首先判断两CString对象data成员是否为空指针 if (source.data == nullptr || this->data == nullptr) { return source.data == nullptr && this->data == nullptr; } int length = (int)strlen(data); int sourceLength = (int)strlen(source.data); // 字符串长度不等,字符串肯定是不等 if (length != sourceLength) { return false; } else { // 长度相等且data指向相同肯定等 if (source.data == this->data) { return true; } } // 以上情况都不符合时才进行逐字比较 int compareLength = std::min(sourceLength, length); for (int i = 0; i < compareLength; ++i) { if (data[i] != source.data[i]) { return false; } } return true; } /* * 从源中复制字符串来构建新的对象 */ CString::CString(char *source) : CString((int)strlen(source)) { strcpy(data, source); } /* * 从源中复制字符串来构建新的对象,并定义初始长度,小于源字符串则会被截取 */ CString::CString(char *source, int length) : CString(length) { strncpy(data, source, length); } CString &CString::operator=(const CString &source) { // 处理自己给自己赋值的情况,那叫啥,自赋值 if (this == &source) { return *this; } delete[] data; // 等号右侧空指针的话直接data赋为空指针 // 这里在执行前就已经delete掉data的数据了,不会泄漏 if (source.data == nullptr) { this->data = nullptr; return *this; } int sourceLength = (int)strlen(source.data); this->data = new char[sourceLength](); strcpy(data, source.data); return *this; } CString &CString::operator+=(const CString &source) { // nullptr不做处理 if(source.data == nullptr) { return *this; } int sourceLength = (int)strlen(source.data); int length = 0; // 本对象nullptr的话就直接新分配 if (data == nullptr) { this->data = new char[sourceLength](); length = sourceLength; } else { length = (int)strlen(data); } // 保存拼接前的原数据,以便重新分配足够的内存 char *old = new char[length](); strcpy(old, data); // 重新分配内存,防止拼接后溢出 length += sourceLength; delete[] data; this->data = new char[length](); strcpy(data, old); strcat(data, "--"); strncat(data, source.data, sourceLength); return *this; } CString::CString(const CString &source) : CString(source.data) {} /* * 按照字典顺序逐字对比 */ bool CString::operator>(const CString &source) const { // 首先判断两CString对象data成员是否为空指针,空直接返回false if (source.data == nullptr || this->data == nullptr) { std::cout << "nullptr!"<< std::endl; return false; } int length = (int)strlen(data); int sourceLength = (int)strlen(source.data); // 两对象指向data同一内存区域并且长度相等则可以判断两字符串相等,所以就不是"<" if (sourceLength == length && source.data == this->data) { std::cout << "memsame" << std::endl; return false; } // 以上情况都不符合时才进行逐字比较 int compareLength = std::min(sourceLength, length); for (int i = 0; i < compareLength; ++i) { if (data[i] > source.data[i]) { std::cout << "data[i]: " << data[i] << " source.data[i]: " << source.data[i] << std::endl; return true; } } return false; } std::ostream &operator<<(std::ostream &outputStream, const CString &source) { return outputStream << source.data; } std::istream &operator>>(std::istream &inputStream, const CString &source) { return inputStream >> source.data; }