自己封装String类
2016-09-16 11:17
197 查看
#include<iostream> #include<assert.h> using namespace std; class MyString { public: MyString(); MyString(const MyString&); MyString(const char*); MyString(const size_t, const char); ~MyString(); size_t Length(); // 字符串长度 bool empty(); // 字符串是否为空 const char *c_str(); // 返回c风格的字符串的指针 // 读写操作符 friend ostream &operator<<(ostream&, const MyString &); friend istream &operator>>(istream&, MyString&); // + friend MyString operator+(const MyString&, const MyString&); // 比较操作符 friend bool operator == (const MyString&, const MyString&); friend bool operator != (const MyString&, const MyString&); friend bool operator < (const MyString&, const MyString&); friend bool operator <= (const MyString&, const MyString&); friend bool operator > (const MyString&, const MyString&); friend bool operator >= (const MyString&, const MyString&); // 下标操作符 char &operator[](const size_t); const char& operator[](const size_t) const; //赋值操作符 MyString &operator = (const MyString&); // '+='操作符 MyString &operator += (const MyString&); // 成员函数 MyString substr(size_t, size_t); //子串操作 MyString &append(const MyString&); // 添加操作 MyString &insert(size_t, const MyString&); //插入操作 MyString &assign(const MyString&, size_t, size_t); // 替换操作 MyString &erase(size_t, size_t); // 删除操作 private: char *p_Str; size_t strLength; }; MyString::MyString():strLength(0), p_Str(NULL){} MyString::MyString(const MyString &str) { strLength = str.strLength; p_Str = new char[strLength + 1]; strcpy(p_Str, str.p_Str); } MyString::MyString(const char *str) { if(str == NULL) { return; } strLength = strlen(str); p_Str = new char[strLength + 1]; strcpy(p_Str, str); } MyString::MyString(const size_t len, const char ch) { strLength = len; p_Str = new char[strLength + 1]; *(p_Str + strLength) = '\0'; strset(p_Str, ch); //功能:把字符串p_Str中的所有字符都设置成字符ch。说明:返回指向p_Str的指针。 } MyString::~MyString() { delete[] p_Str; } size_t MyString::Length() { return strLength; } bool MyString::empty() { return strLength == 0 ? true : false; } const char *MyString::c_str() { return p_Str; } ostream &operator<<(ostream &out, const MyString &str) { if(str.p_Str != NULL) out<<str.p_Str; return out; } istream &operator>>(istream &in, MyString &str) { char temp[100]; if(in>>temp) { delete[] str.p_Str; str.strLength = strlen(temp); str.p_Str = new char[str.strLength + 1]; strcpy(str.p_Str, temp); } return in; } // 下标操作符 char &MyString::operator[](const size_t index) { assert(index >= 0 && index <= strLength); return p_Str[index]; } const char &MyString::operator[](const size_t index)const { assert(index >= 0 && index <= strLength); return p_Str[index]; } MyString operator+(const MyString &lhs, const MyString &rhs) { MyString ret; ret.strLength = lhs.strLength + rhs.strLength; ret.p_Str = new char[ret.strLength + 1]; strcpy(ret.p_Str, lhs.p_Str); /* 原型声明:char *strcpy(char* dest, const char *src); 头文件:#include <string.h> 和 #include <stdio.h> 功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间 说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 返回指向dest的指针。 */ strcat(ret.p_Str, rhs.p_Str); /* 原型 extern char *strcat(char *dest,char *src); 用法 #include <string.h> 在C++中,则存在于<cstring>头文件中。 功能 把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')。 说明 src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 返回指向dest的指针。 */ } MyString &MyString::operator=(const MyString &str) { if(this != &str) { if(strLength < str.strLength) { delete[] p_Str; p_Str = new char[str.strLength + 1]; } strLength = str.strLength; strcpy(p_Str, str.p_Str); } return *this; } MyString &MyString::operator+=(const MyString &str) { if(this == &str) { MyString copy(str); return *this += copy; } strLength += str.strLength; char *p_Old = p_Str; p_Str = new char[strLength + 1]; strcpy(p_Str, p_Old); delete[] p_Old; strcat(p_Str, str.p_Str); return *this; } bool operator==(const MyString &lhs, const MyString &rhs) { return strcmp(lhs.p_Str, rhs.p_Str) == 0; /* 当s1<s2时,返回为负数; 当s1=s2时,返回值= 0; 当s1>s2时,返回正数。 */ // } bool operator!=(const MyString &lhs, const MyString &rhs) { return strcmp(lhs.p_Str, rhs.p_Str); } bool operator<(const MyString &lhs, const MyString &rhs) { return strcmp(lhs.p_Str, rhs.p_Str) < 0; } bool operator<=(const MyString &lhs, const MyString &rhs) { return strcmp(lhs.p_Str, rhs.p_Str) > 0; } bool operator>(const MyString &lhs, const MyString &rhs) { return strcmp(lhs.p_Str, rhs.p_Str) > 0; } bool operator>=(const MyString &lhs, const MyString &rhs) { return strcmp(lhs.p_Str, rhs.p_Str) >= 0; } //子串操作 //返回一个MyString类型的字符串,它包含源字符串中从下标pos开始的n个字符 MyString MyString::substr(size_t pos, size_t n) { assert(pos + n <= strLength); MyString ret; ret.strLength = n; ret.p_Str = new char[ret.strLength + 1]; for(size_t i = 0; i != n; ++i) { ret[i] = (*this)[pos + i]; } ret = '\0'; return ret; } //添加操作 //将一个字符串的副本添加到源字符串的末尾,同“+=”操作符类似 MyString &MyString::append(const MyString &str) { *this += str; return *this; } //插入操作 //在下标为pos的元素之前插入MyString对象str的副本 MyString &MyString::insert(size_t pos, const MyString &str) { assert(pos < strLength); char *p_Old = p_Str; strLength += str.strLength; p_Str = new char[strLength + 1]; for(size_t i = 0; i != pos; i++) { *(p_Str + i) = *(p_Old + i); } for(size_t i=pos;i!=str.strLength+pos;++i) *(p_Str+i) = *(str.p_Str+i-pos); for(size_t i=str.strLength+pos;i!=strLength;++i) *(p_Str+i) = *(p_Old+i-str.strLength); *(p_Str+strLength)='\0'; delete[] p_Old; return *this; } //替换操作 //用s2中从下标pos开始的len个字符副本替换源字符串 MyString& MyString::assign(const MyString& s2,size_t pos,size_t len) { if(strLength<len) { strLength = len; delete[] p_Str; p_Str = new char[strLength+1]; } for(size_t i=0;i!=len;++i) *(p_Str+i)=s2[pos+i]; *(p_Str+strLength)='\0'; return *this; } //删除操作 //删除从下标pos开始的len个字符 MyString& MyString::erase(size_t pos,size_t len) { assert(pos+len<=strLength); size_t index = pos + len; while(*(p_Str+index)!='\0') { *(p_Str+index-len)=*(p_Str+index); ++index; } *(p_Str+index-len)='\0'; return *this; } int main() { // system("pause"); return 0; }
#include<iostream>
using namespace std;
class MyString
{
public:
MyString();
MyString(const char *str = 0);
MyString(const MyString &other); //拷贝构造函数
~MyString();
MyString &operator=(const MyString &other);
private:
char *m_Data;
};
//默认构造函数
MyString::MyString()
{
m_Data = new char[1];
*m_Data = 0;
}
//自定义构造函数
MyString::MyString(const char *str)
{
if(str == 0)
{
m_Data = new char[1];
*m_Data = 0;
}
else
{
m_Data = new char[strlen(str)];
strcpy(m_Data, str);
}
}
//拷贝构造函数
MyString::MyString(const MyString &other)
{
m_Data = new char[strlen(other.m_Data) + 1];
strcpy(m_Data, other.m_Data);
}
//析构函数
MyString::~MyString()
{
delete[] m_Data;
}
//重载赋值运算符函数
MyString::&MyString::operator=(const MyString &other)
{
//自检查,防止自己赋值给自己
if(this == &other)return *this;
//删除原来的内存资源
delete[] m_Data;
m_Data = new char[strlen(other.m_Data) + 1];
strcpy(m_Data, other.m_Data);
return *this;
}
相关文章推荐
- 自己动手封装一个string类
- 封装自己的控件库:iPhone静态库的应用
- 封装一个自己的php操作类
- [置顶]cocos2d-x 中文显示问题的解决方案 (自己封装一个类一次编写终身无忧)
- VB.net 调用自己封装起来的用VB.net做的DLL
- javascript如何封装自己的js插件
- 封装自己的js框架入门
- Android 6.0 的权限管理自己简单的封装--(到BaseActivity)
- 【java】自己封装的httpHelper访问类及其相关联的类 访问http
- [Unity3d]调用自己封装的dll
- js笔记---封装自己的Ajax方法
- 自己封装socket(更新啦)
- 从NSURLSession到AFNetworking再到自己封装一个网络框架
- js-封装自己的class类
- 封装自己的LINUX光盘
- 封装自己的addEvent
- 一步一步的来封装自己的RecycleView
- 自己diy封装xp操作系统
- 图片加载未完成时的默认背景图处理(仅限自己封装的图片加载工具)
- 自己封装的AJAX (带JSON)