您的位置:首页 > 其它

MyString类的实现

2016-04-14 21:43 148 查看
string类在c++中使得程序员对于字符串的操作更加方便,今天就来编写自己的MyString类。

先来看mystring.h的定义:

#ifndef _MYSTRING_H_
#define _MYSTRING_H_

#include<iostream>
using namespace std;

class MyString{
public:
MyString();
MyString(const char* str);
MyString(const size_t len,const char ch);
MyString(const MyString& t);
~MyString();
public:
//属性
size_t length();
bool empty();
const char* c_str();    //返回C风格字符串指针
//读写操作
friend ostream& operator<< (ostream& out,const MyString& str);
friend istream& operator>> (istream& in, MyString& str);
//'+'操作
friend MyString operator+ (const MyString& str1,const MyString& str2);
//比较操作
friend bool operator== (const MyString& str1,const MyString& str2);
friend bool operator!= (const MyString& str1,const MyString& str2);
friend bool operator< (const MyString& str1,const MyString& str2);
friend bool operator<= (const MyString& str1,const MyString& str2);
friend bool operator> (const MyString& str1,const MyString& str2);
friend bool operator>= (const MyString& str1,const MyString& str2);

//下标操作
char& operator[] (const size_t);
const char& operator[] (const size_t)const;
//赋值操作
MyString& operator= (const MyString& str);
//'+='操作
MyString& operator+= (const MyString& str);
//子串操作
MyString substr(size_t,size_t);
//添加操作
MyString& append(const MyString& str);
//插入操作
MyString& insert(size_t,const MyString&);
//替换操作
MyString& assign(const MyString&,size_t,size_t);
//删除操作
MyString& erase(size_t,size_t);
private:
char *base;
size_t strlength;
};

#endif


接下来来看具体的实现:

#include<iostream>
#include<string>
#include<string.h>
#include<assert.h>
#include"mystring.h"

MyString::MyString()
{
base = NULL;
strlength = 0;
}
MyString::MyString(const char* str)
{
if(str == NULL){
return ;
}
strlength = strlen(str);
base = new char[strlength + 1];
strcpy(base,str);
}
MyString::MyString(size_t len,const char ch)
{
strlength = len;
base = new char[strlength + 1];
base[strlength + 1] = '\0';
for(int i = 0;i< strlength;++i){
base[i] = ch;
}
}
MyString::MyString(const MyString& t)
{
this->strlength = t.strlength;
base = new char[strlength + 1];
strcpy(base,t.base);
}
MyString::~MyString()
{
delete []base;
}
size_t MyString::length()
{
return strlength;
}
bool MyString::empty()
{
return strlength == 0 ? true : false;
}

const char* MyString:: c_str()    //返回C风格字符串指针
{
return base;
}
//下标操作
char& MyString::operator[] (const size_t index)
{
assert(index >=0 && index <= strlength);
return base[index];
}
const char& MyString::operator[] (const size_t index)const
{
assert(index >=0 && index <= strlength);
return base[index];
}
//赋值操作
MyString& MyString::operator= (const MyString& str)
{
if(this != &str){
delete []base;
base = new char[str.strlength + 1];
strlength = str.strlength ;
strcpy(base,str.base);
}
return *this;
}
//'+='操作
MyString& MyString::operator+= (const MyString& str)
{
if(this != &str){
strlength += str.strlength;
char *p_str;
p_str = new char[strlength + 1];
strcpy(p_str,base);
delete []base;
strcat(p_str,str.base);
base = p_str;
return *this;
}
MyString copy(str);
return *this += copy;
}
//子串操作
//返回一个MyString 类型的字符串,它包含源字符串中从下标pos开始的n个字符
MyString MyString::substr(size_t pos,size_t n)
{
assert(pos + n <= strlength);
MyString ret;
ret.strlength = n;
ret.base = new char[ret.strlength + 1];
for(size_t i = 0;i < n;++i){
ret[i] = base[pos + i];
}
ret[ret.strlength] = '\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);
int len = str.strlength;
int len1 = strlength ;
char *p_str;
int i;
strlength += str.strlength;
p_str  = new char[strlength + 1];
for(i = 0; i < pos;++i){
p_str[i] = base[i];
}
for(int j = 0 ; j < str.strlength;++j){
p_str[i++] = str[j];
}
for(int k = pos ; k <= len1;++k){
p_str[i++] = base[k];
}
p_str[strlength] = '\0';
delete []base;
base = p_str;
return *this;
}
//替换操作
//用s2中下标pos开始的len个字符副本替换源字符串
MyString& MyString::assign(const MyString& s2,size_t pos,size_t len)
{
if(strlength < len){
char* p_str = new char[len + 1];
strlength = len;
delete []base;
base = p_str;
}
int i;
for(i = 0;i < len;++i){
base[i] = s2[i];
}
base[strlength] = '\0';
return *this;
}
//删除操作
//删除从下标pos开始的len的字符
MyString& MyString::erase(size_t pos,size_t len)
{
assert(pos + len <= strlength);
for(int i = pos ,j = pos + len ; i < pos + len && j <= strlength ; ++i,++j){
base[i] = base[j];
}
strlength -= len;
base[strlength] = '\0';
return *this;
}

//读写操作
ostream& operator<<(ostream& out,const MyString& t)
{
if(t.base != NULL){
cout << t.base;
}
return out;
}
istream& operator>> (istream& in, MyString& str)
{
char tmp[100];
if(in >> tmp){
delete []str.base;
str.strlength = strlen(tmp);
str.base = new char[str.strlength + 1];
strcpy(str.base,tmp);
}
return in;
}
//'+'操作
MyString operator+ (const MyString& str1,const MyString& str2)
{
MyString ret;
ret.strlength = str1.strlength + str2.strlength ;
ret.base = new char[ret.strlength + 1];
strcpy(ret.base,str1.base);
strcat(ret.base,str2.base);
return ret;
}
//比较操作
bool operator== (const MyString& str1,const MyString& str2)
{
return strcmp(str1.base , str2.base) == 0;
}
bool operator!= (const MyString& str1,const MyString& str2)
{
return strcmp(str1.base , str2.base) != 0;
}
bool operator< (const MyString& str1,const MyString& str2)
{
return strcmp(str1.base , str2.base) < 0;
}
bool operator<= (const MyString& str1,const MyString& str2)
{
return strcmp(str1.base , str2.base) <= 0;
}
bool operator> (const MyString& str1,const MyString& str2)
{
return strcmp(str1.base , str2.base) > 0;
}
bool operator>= (const MyString& str1,const MyString& str2)
{
return strcmp(str1.base , str2.base) >= 0;
}


测试程序:

#include<iostream>
#include<string>
#include"mystring.h"
#include<string.h>
using namespace std;
int main(int argc,char**argv)
{
MyString s;
MyString s1("hello");
MyString s2(10,'h');
MyString s3 = s1;
MyString s4("world");
MyString s5(10,'e');
MyString s6("family");
const char *str = s.c_str();
const char *str1 = s1.c_str();
const char *str2 = s2.c_str();
const char *str3 = s3.c_str();
#if 1
cout << s <<endl;
cout << "s length : " << s.length() << endl;
if(s.empty()){
cout << "s is empty!"<<endl;
}else{
cout << "s is not empty!!" << endl;
}

cout << s1 <<endl;
cout << "s1 length : " << s1.length() << endl;
if(s1.empty()){
cout << "s1 is empty!"<<endl;
}else{
cout << "s1 is not empty!!" << endl;
}

cout << s2 <<endl;
cout << "s2 length : " << s2.length() << endl;
if(s2.empty()){
cout << "s2 is empty!"<<endl;
}else{
cout << "s2 is not empty!!" << endl;
}

cout << s3 <<endl;
cout << "s3 length : " << s3.length() << endl;
if(s3.empty()){
cout << "s3 is empty!"<<endl;
}else{
cout << "s3 is not empty!!" << endl;
}

//cout << "s c_str(): " << str << endl;
cout << "s1 c_str(): " << str1 << endl;
cout << "s2 c_str(): " << str2 << endl;
cout << "s3 c_str(): " << str3 << endl;

cout << "s1[] :" << endl;
for(int i = 0;i <= s1.length() ;++i){
cout << s1[i] << " ";
}
cout << endl;

cout << "s2[] :" << endl;
for(int i = 0;i <= s2.length() ;++i){
cout << s2[i] << " ";
}
cout << endl;

cout << "s3[] :" << endl;
for(int i = 0;i <= s3.length() ;++i){
cout << s3[i] << " ";
}
cout << endl;

s3 = s2;
cout << "s3 = s2 : " << endl;
cout << "s3 : "<< s3 << endl;

s1 += s4;
cout << "s1 += s4 : " << s1 << endl;
s1 += s1;
cout << "s1 += s1 : " << s1 << endl;

s2 += s1;
cout << "s2 += s1 : " << s2 << endl;
s2 += s2;
cout << "s2 += s2 : " << s2 << endl;
#endif
s = s1.substr(0,4);
cout << "s1.substr(): " << s << endl;

#if 1
s4 = s1.append(s4);
cout <<"s1: " << s1 <<endl;
cout <<"s4: " << s4 <<endl;

cout << "s4 : " << s4 << endl;
cout << "s5 : " << s5 << endl;
s4.insert(1,s5);
cout << "s4 (befor 1)insert s5 :    " << endl ;
cout << "s4 : " << s4 << endl;
cout << endl;

cout << "s5 : " << s5 << endl;
cout << "s6 : " << s6 << endl;
s6.insert(1,s5);
cout << "s6 (befor 1) insert s5 :    " << endl ;
cout << "s5 : " << s5 << endl;
cout << "s6 : " << s6 << endl;
cout << endl;

#endif
#if 1
cout << "s2 : " << s2 << endl;
cout << "s6 : " << s6 << endl;
s6.assign(s2,0,10);
cout << "s2 (0,10) assgin s6:    " << endl ;
cout << "s2 : " << s2 << endl;
cout << "s6 : " << s6 << endl;
cout << endl;

cout << "s2 : " << s2 << endl;
cout << "s6 : " << s6 << endl;
s6.assign(s2,0,20);
cout << "s2 (0,20) assgin s6:    " << endl ;
cout << "s2 : " << s2 << endl;
cout << "s6 : " << s6 << endl;
cout << "s5 :" << endl;
cout << s5 << endl;
cout << "s6 :" << endl;
cout << s6 << endl;

cout << "s6 : " <<endl;
cout << s6 << endl;
s6.erase(1,15);
cout << "s6 erase : " <<endl;
cout << s6 << endl;

cout << "s5 :" << endl;
cout << s5 << endl;
cout << "s6 :" << endl;
cout << s6 << endl;
s6 = s5 + s6;
cout << "s6  = s5 + s6 " << endl;
cout << s6 << endl;

cout << endl;

cout << "s5 :" << endl;
cout << s5 << endl;
cout << "s6 :" << endl;
cout << s6 << endl;
if(s5 > s6){
cout << "s5 > s6 " << endl;
}

if(s5 >= s6){
cout << "s5 >= s6 " << endl;
}

if(s5 == s6){
cout << "s5 == s6 " << endl;
}

if(s5 != s6){
cout << "s5 != s6 " << endl;
}

if(s5 < s6){
cout << "s5 < s6 " << endl;
}

if(s5 <= s6){
cout << "s5 <= s6 " << endl;
}
#endif
return 0;
}


部分执行结果:





通过string类的编写更加深刻体会到c++的面向对象的特点,之后还会继续对继承和多态,甚至设计模式都会有比较深的理解的。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: