C++ string 类 部分成员函数实现(实现COW copy-on-write)
2017-05-02 23:12
357 查看
虽然标题中说实现了COW,但是事实上是很浪费的,并且命名也很不标准,代码也非常小学生,毕竟初学(给自己找借口.jpg),以后应该还会把这篇找出来认真修改一下的。
Mystring.h:
犯得一个奇蠢无比的错误是,注意到string的一个特点就是不以/0判断字符串的终止,所以用cstring中的函数也要记得这一点,例如strcmp就会因为/0而终止,而影响正常的比较,所以更推荐用memcmp。
Mystring.h:
#pragma once #ifndef _MYSTRING_H_ #define _MYSTRING_H_ #include <iostream> #include <cstring> using namespace std; class Mystring { public: friendostream & operator << (ostream & os, Mystring & s); friendostream & operator << (ostream & os, const Mystring & s); Mystring();//default constructor Mystring(constchar * s); // 用c字符串s初始化 Mystring(constMystring& string2);//copy constructor virtual~Mystring();//destructor int size()const; voidappend(const char* s); voidappend(const Mystring& s); char&operator[](int index); char &operator[](int index) const; char*getString() const; booloperator ==(const Mystring & s) const; booloperator !=(const Mystring & s) const; booloperator < (const Mystring & s) const; booloperator > (const Mystring & s) const; booloperator <=(const Mystring & s) const; booloperator >=(const Mystring & s) const; private: char*m_szstring; int m_isize; }; #endif Mystring.cpp #include "Mystring.h" #include <cstring> #include <iostream> #define _SIZE_1000 using namespace std; Mystring::Mystring():m_isize(0) { m_szstring =new char[1]; m_szstring[1]= 1; } Mystring::Mystring(const char * s):m_isize(strlen(s)) { //autos_size = strlen(s); //m_isize =strlen(s); m_szstring =new char[m_isize+1]; m_szstring[m_isize+ 1] = 1;//该属性属于当前地址,当前地址只被自己引用 strncpy(m_szstring,s,m_isize); //cout<< "Mystring(const char * s)" << endl; } Mystring::Mystring(const Mystring & string2) { this->m_isize= string2.m_isize; this->m_szstring= string2.m_szstring;//sharing memory m_szstring[m_isize+1]++;//引用数加一 memcpy(this->m_szstring,string2.m_szstring, string2.m_isize+1); //cout<< "Mystring::Mystring(Mystring & string2)" << endl; } Mystring::~Mystring() { //cout<< "Mystring::~Mystring()"<< this->size()<<endl; m_szstring[m_isize+ 1]--; if(!m_szstring[m_isize+1])//如果当前地址引用者等于零,delete { delete[]m_szstring; } } ostream& operator< a950 ;<(ostream& os, Mystring&s) { for (int i =0; i < s.size(); i++) { os<< s.m_szstring[i]; } return os; } ostream& operator<<(ostream& os, constMystring &s) { for (int i =0; i < s.size(); i++) { os<< s.m_szstring[i]; } return os; } int Mystring::size() const { returnthis->m_isize; } char& Mystring::operator[](int index) { if(m_szstring[m_isize+1]>1) { m_szstring[m_isize+ 1]--; char*temp = new char[m_isize + 1]; strncpy(temp,m_szstring,m_isize); m_szstring= temp; m_szstring[m_isize+ 1] = 1; //cout<< "surprise mf! >v<" << endl; } returnm_szstring[index]; } char& Mystring::operator[](int index) const { returnthis->m_szstring[index]; } char * Mystring::getString() const { returnthis->m_szstring; } bool Mystring::operator==(const Mystring & s) const { if (m_isize!= s.m_isize)return false; return!memcmp(m_szstring,s.m_szstring,m_isize);//strncmp???因为遇到零会停止啊笨蛋!!!! } bool Mystring::operator!=(const Mystring & s) const { return!((*this)==s); } bool Mystring::operator<(const Mystring & s) const { //if(m_isize > s.m_isize) //{ // return false; //}; const int_minLen = m_isize < s.m_isize ? m_isize : s.m_isize; long long_result = memcmp(m_szstring, s.m_szstring, _minLen); if (_result== 0) { returnm_isize < s.m_isize; } else { return_result < 0; } } bool Mystring::operator>(const Mystring & s) const { return(s<(*this)); } bool Mystring::operator<=(const Mystring & s)const { return!(s<(*this)); } bool Mystring::operator>=(const Mystring & s)const { return!((*this)<s); } void Mystring::append(const char * s) { if (s ==NULL) { //cout<< "invalid input" << endl; return; } if(m_szstring) { char*temp = m_szstring; m_szstring= new char[m_isize + strlen(s) + 1]; memcpy(m_szstring,temp, m_isize); temp[m_isize+ 1]--; if(!temp[m_isize + 1]) { delete[]temp; } //m_szstring= temp; memcpy(m_szstring+ m_isize, s, strlen(s)); m_isize= m_isize + strlen(s); m_szstring[m_isize+ 1] = 1; } else { m_isize= strlen(s); m_szstring= new char[m_isize+1]; strcpy(m_szstring,s); m_szstring[m_isize+ 1] = 1; } } void Mystring::append(const Mystring & s) { if(s.m_szstring == NULL) { return; } if(s.m_szstring) { char*temp = m_szstring; m_szstring= new char[m_isize + s.m_isize + 1]; memcpy(m_szstring,temp, m_isize); temp[m_isize+ 1]--; if(!temp[m_isize + 1]) { delete[]temp; } //m_szstring= temp; //delete[]temp; memcpy(m_szstring+ m_isize, s.m_szstring, s.m_isize); m_isize= m_isize + s.m_isize; m_szstring[m_isize+ 1] = 1; } else { this->m_isize= s.m_isize; this->m_szstring= new char[m_isize + 1]; memcpy(this->m_szstring,s.m_szstring, s.m_isize); m_szstring[m_isize+ 1] = 1; } }
犯得一个奇蠢无比的错误是,注意到string的一个特点就是不以/0判断字符串的终止,所以用cstring中的函数也要记得这一点,例如strcmp就会因为/0而终止,而影响正常的比较,所以更推荐用memcmp。
相关文章推荐
- C++ string 类 部分成员函数实现(实现COW copy-on-write+实现智能指针(有极大bug版本))
- Item 45: 利用成员函数模板接受所有兼容类型(智能指针的部分实现)
- 如何实现利用类成员函数创建线程
- 获得全局函数和成员函数指针的部分traits的方法
- 利用C++模板,代替虚函数,实现类的静态多态性(加入性能测试部分)
- 如何在类中实现回调成员函数
- 对于日期指定部分的加减 使用DATEADD函数就可以轻松实现
- 利用一组宏定义实现类成员函数的回调
- C语言部分函数原型实现
- 借shared_ptr实现copy-on-write
- 实现不需要辅助函数实现回调非静态类成员函数
- 编程练习- 尝试写出String类的成员函数实现
- 如何实现利用类成员函数创建线程
- 如何在类中实现回调成员函数
- 使用 IIS 进行 Microsoft ASP.NET 2.0 成员/角色管理,第 2 部分:实现
- 如何实现类的成员函数创建线程
- 如何实现利用类成员函数创建线程 选择自 iceezone 的 Blog
- 利用C++模板,代替虚函数,实现类的静态多态性(加入性能测试部分)
- 使用 XForms 和 Ruby on Rails 开发小型门诊管理系统,第 2 部分:实现患者信息 Xform
- 如何实现类的成员函数创建线程