虽然标题中说实现了COW,但是事实上是很浪费的,并且命名也很不标准,代码也非常小学生,毕竟初学(给自己找借口.jpg),以后应该还会把这篇找出来认真修改一下的。
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<<(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。