标签:
字符串类(String),熟悉内存管理与拷贝控制
#include <iostream> //#include <cstring> using std::cout; using std::cin; class String{ using iterator = char *; friend std::ostream &operator<< (std::ostream &, const String &); friend std::istream &operator>> (std::istream &, String &); friend String operator + (const String &, const String &); friend String operator + (const String &, const char *); //对于非类内的函数,必须参数中存在类类型的参数; friend String operator + (const char *, const String &); //否则会与默认类型的操作符冲突 friend unsigned int getline(std::istream &, String &); public: String(const char *rhs = "hello, world"); //构造函数,默认为"hello, world" 通常我们可以默认为NULL String(const String &); //拷贝构造函数 String &operator= (const String&); //拷贝赋值运算符 String &operator= (const char *); //拷贝赋值运算符 String & operator += (const String&); String & operator += (const char *); char operator[] (int); iterator begin(); iterator end(); String & push_back(const char); String & clear(); ~String() { delete [] data; } //析构函数 private: char *data; }; std::ostream & operator<< (std::ostream &, const String &); std::istream &operator>> (std::istream &, String &); inline String::String(const char *rhs) { if (!rhs) //必须先检查rhs是否为NULL;对于NULL的拷贝,会去读取未知地址 data = new char[1]{0}; //因为我们的析构函数调用了delete,所以必须开辟一个空间, //否则代码在调用析构函数时会delete一个错误空间 else { data = new char[strlen(rhs) + 1]; strcpy(data, rhs); } } inline String& String::operator= (const String& rhs) //拷贝赋值运算 { this->data = new char[strlen(rhs.data) + 1]; strcpy(this->data, rhs.data); return *this; } inline String & String::operator= (const char *rhs) //拷贝赋值运算符 { this->data = new char[strlen(rhs) + 1]; strcpy(this->data, rhs); return *this; }
#include "String.h" inline String::String(const String &rhs) //拷贝构造函数 { data = new char[strlen(rhs.data) + 1]; //每次都要 +1 的原因是strlen不包含最后的‘\0‘ strcpy(data, rhs.data); } std::ostream &operator<< (std::ostream &os, const String &rhs) { os << rhs.data; return os; } std::istream& operator >> (std::istream &is, String &rhs) { is >> rhs.data; return is; } String & String::operator += (const String &rhs) { if (!rhs.data) //如果要加的类的数据为NULL,则不需要处理了 return *this; else if (!data) //如果原来的数据为NULL,则直接把后来的数据拷贝过来;由于上面的判断,所以rhs.data != NULL; { this->data = new char[strlen(rhs.data) + 1]; strcpy(this->data, rhs.data); return *this; } else //data != NULL && rhs.data != NULL { char *tmp = new char[strlen(this->data) + 1]; strcpy(tmp, this->data); this->data = new char[strlen(data) + strlen(rhs.data) + 1]; strcpy(data, tmp); strcat(data, rhs.data); free(tmp); return *this; } } String & String::operator += (const char * rhs) { if (!rhs) //如果要加的类的数据为NULL,则不需要处理了 return *this; else if (!data) //如果原来的数据为NULL,则直接把后来的数据拷贝过来;由于上面的判断,所以rhs.data != NULL; { this->data = new char[strlen(rhs) + 1]; strcpy(this->data, rhs); return *this; } else //data != NULL && rhs.data != NULL { char *tmp = new char[strlen(this->data) + 1]; strcpy(tmp, this->data); this->data = new char[strlen(data) + strlen(rhs) + 1]; strcpy(data, tmp); strcat(data, rhs); free(tmp); return *this; } } String operator + (const String &lhs, const String &rhs) { String tmp(lhs); tmp += rhs; return tmp; } String operator + (const String &lhs, const char *rhs) { String tmp(lhs); tmp += rhs; return tmp; } String operator + (const char *lhs, const String &rhs) { String tmp(lhs); tmp += rhs; return tmp; } String::iterator String::begin() { return data; } String::iterator String::end() { return data + strlen(data); } char String::operator[] (int index) { if (index > strlen(data) - 1 || index < 0) { cout << "index error"; return 0; } else return *(data + index); } String & String::push_back(const char ch) { char *tmp = new char[strlen(data) + 2]; strcpy(tmp, data); *(tmp + strlen(data)) = ch; //data + strlen(data)是原来的‘\0‘处 *(tmp + strlen(data) + 1) = ‘\0‘; data = new char[strlen(data) + 2]; strcpy(data, tmp); //free(tmp); delete[] tmp; //delete [] tmp = free(tmp) : 怀疑delete就是把free封装了 return *this; } String & String::clear() { delete[] data; data = new char[]{0}; return *this; } unsigned int getline(std::istream &is, String & rhs) { char tmp; rhs.clear(); while (is.get(tmp)) { if (tmp && tmp != ‘\n‘) rhs.push_back(tmp); else break; } return strlen(rhs.data); }
标签:
原文地址:http://www.cnblogs.com/dylqt/p/4928577.html