#include <string.h>
#include <iostream>
using std::cout;
using std::endl;
class String
{
public:
//String s1;
String()
: _pstr(new char[5]() + 4)//1 '\0' 2-5 RefCount int
{
cout << "String()" << endl;
initRefCount();
}
//String s1("hello");
String(const char *pstr)
: _pstr(new char[strlen(pstr) + 5]() + 4)
{
cout << "String(const char *)" << endl;
strcpy(_pstr, pstr);
initRefCount();
}
//String s2(s1);
String(const String &rhs)
: _pstr(rhs._pstr)//浅拷贝
{
cout << "String(const String &)" << endl;
increaseRefCount();
}
//String s3("world");
//s3 = s1
String &operator=(const String &rhs)
{
if(this != &rhs)//1、自复制
{
//2、释放左操作
release();
//3、深拷贝(浅拷贝)
_pstr = rhs._pstr;
increaseRefCount();
}
return *this;//4、返回*this
}
private:
class CharProxy
{
public:
CharProxy(String &self, size_t idx)
: _self(self)
, _idx(idx)
{
}
char &operator=(const char &ch);//写操作
friend std::ostream &operator<<(std::ostream &os, const CharProxy &rhs);
private:
String &_self;//此时String是不完整类型
size_t _idx;
};
public:
//下边访问运算符
//s3[0] = 'H'
//cout <<"s1[0] = " << s1[0] << endl;
CharProxy operator[](size_t idx)//String *this
{
return CharProxy(*this, idx);
}
#if 0
char &operator[](size_t idx)
{
if(idx < this->size())
{
if(getRefCount() > 1)//考虑共享问题
{
char *ptmp = new char[size() + 5]() + 4;
strcpy(ptmp, _pstr);
decreaseRefCount();
_pstr = ptmp;
initRefCount();
}
return _pstr[idx];
}
else
{
static char charnull = '\0';
return charnull;
}
}
#endif
//s3
~String()
{
cout << "~String()" << endl;
release();
}
public:
const char *c_str() const
{
return _pstr;
}
int getRefCount() const
{
return *(int *)(_pstr - 4);
}
private:
size_t size() const
{
return strlen(_pstr);
}
void initRefCount()
{
*(int *)(_pstr - 4) = 1;
}
void increaseRefCount()
{
++*(int *)(_pstr - 4);
}
void decreaseRefCount()
{
--*(int *)(_pstr - 4);
}
void release()
{
decreaseRefCount();
if(0 == getRefCount())
{
delete [] (_pstr - 4);
}
}
friend std::ostream &operator<<(std::ostream &os, const String &rhs);
friend std::ostream &operator<<(std::ostream &os, const String::CharProxy &rhs);
private:
char *_pstr;
};
std::ostream &operator<<(std::ostream &os, const String &rhs)
{
if(rhs._pstr)
{
os << rhs._pstr;
}
return os;
}
//CharProxy里面的函数
//s3[0] = 'H'
char &String::CharProxy::operator=(const char &ch)
{
if(_idx < _self.size())
{
if(_self.getRefCount() > 1)//考虑共享问题
{
char *ptmp = new char[_self.size() + 5]() + 4;
strcpy(ptmp, _self._pstr);
_self.decreaseRefCount();
_self._pstr = ptmp;
_self.initRefCount();
}
_self._pstr[_idx] = ch;//真正的赋值操作
return _self._pstr[_idx];
}
else
{
static char charnull = '\0';
return charnull;
}
}
//双友元的设置
std::ostream &operator<<(std::ostream &os, const String::CharProxy &rhs)
{
os << rhs._self._pstr[rhs._idx];
return os;
}
void test()
{
String s1("hello");
String s2(s1);
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s1.getRefCount() = " << s1.getRefCount() << endl;
cout << "s2.getRefCount() = " << s2.getRefCount() << endl;
printf("s1'address : %p\n", s1.c_str());
printf("s2'address : %p\n", s2.c_str());
cout << endl;
String s3("world");
cout << "s3 = " << s3 << endl;
cout << "s3.getRefCount() = " << s3.getRefCount() << endl;
printf("s3'address : %p\n", s3.c_str());
cout << endl << "使用s3 = s1进行赋值操作" << endl;
s3 = s1;
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s1.getRefCount() = " << s1.getRefCount() << endl;
cout << "s2.getRefCount() = " << s2.getRefCount() << endl;
cout << "s3.getRefCount() = " << s3.getRefCount() << endl;
printf("s1'address : %p\n", s1.c_str());
printf("s2'address : %p\n", s2.c_str());
printf("s3'address : %p\n", s3.c_str());
cout << endl << "对s3[0]执行写操作" << endl;
s3[0] = 'H';//'h' = 'H' char = char// CharProxy = char//"hello"
s3.operator[](0).operator=('H');
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s1.getRefCount() = " << s1.getRefCount() << endl;
cout << "s2.getRefCount() = " << s2.getRefCount() << endl;
cout << "s3.getRefCount() = " << s3.getRefCount() << endl;
printf("s1'address : %p\n", s1.c_str());
printf("s2'address : %p\n", s2.c_str());
printf("s3'address : %p\n", s3.c_str());
cout << endl << "对s1[0]执行读操作" << endl;
cout << "s1[0] = " << s1[0] << endl;//cout << CharProxy//CharProxy -> char
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s1.getRefCount() = " << s1.getRefCount() << endl;
cout << "s2.getRefCount() = " << s2.getRefCount() << endl;
cout << "s3.getRefCount() = " << s3.getRefCount() << endl;
printf("s1'address : %p\n", s1.c_str());
printf("s2'address : %p\n", s2.c_str());
printf("s3'address : %p\n", s3.c_str());
}
int main(int argc, char **argv)
{
test();
return 0;
}
#include <string.h>
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
class String
{
public:
String()
// : _pstr(nullptr)//后面操作的时候,需要判空
: _pstr(new char[1]())
{
cout << "String()" << endl;
}
//String s1("hello")
String(const char *pstr)
: _pstr(new char[strlen(pstr) + 1]())
{
cout << "String(const char *)" << endl;
strcpy(_pstr, pstr);
}
//String s2(s1);
String(const String &rhs)
: _pstr(new char[strlen(rhs._pstr) +1]())
{
cout << "String(const String &)" << endl;
strcpy(_pstr, rhs._pstr);
}
~String()
{
cout << "~String()" << endl;
if(_pstr)
{
delete [] _pstr;
_pstr = nullptr;
}
}
//String s1;
//s1 = s1;
String &operator=(const String &rhs)
{
cout << "String &operator=(const String &)" << endl;
if(this != &rhs)
{
delete [] _pstr;
_pstr = nullptr;
_pstr = new char[strlen(rhs._pstr) + 1]();
strcpy(_pstr, rhs._pstr);
}
return *this;
}
// s1 = "hello";
String &operator=(const char *pstr)
{
cout << "String &operator=(const char *)" << endl;
String tmp(pstr);
*this = tmp;
return *this;
}
//s1 += s2;
String &operator+=(const String &rhs)
{
cout << "String &operator+=(const String &)" <<endl;
String tmp;
if(tmp._pstr)
{
delete [] tmp._pstr;//防止内存泄漏
}
tmp._pstr = new char[strlen(_pstr) + 1]();
strcpy(tmp._pstr, _pstr);
delete [] _pstr;
_pstr = nullptr;
_pstr = new char[strlen(rhs._pstr) + strlen(tmp._pstr) + 1]();
strcpy(_pstr, tmp._pstr);
strcat(_pstr, rhs._pstr);
return *this;
}
//s1 += "hello"
String &operator+=(const char *pstr)
{
cout << "String &operator+=(const char *)" << endl;
String tmp(pstr);
*this += tmp;
return *this;
}
//const String s1("helo");
//s1[0]
char &operator[](std::size_t index)//index > = 0
{
if(index < size())
{
return _pstr[index];
}
else
{
static char nullchar = '\0';
return nullchar;
}
}
const char &operator[](std::size_t index) const
{
if(index < size())
{
return _pstr[index];
}
else
{
static char nullchar = '\0';
return nullchar;
}
}
std::size_t size() const
{
return strlen(_pstr);
}
const char* c_str() const
{
return _pstr;
}
friend bool operator==(const String &, const String &);
friend bool operator!=(const String &, const String &);
friend bool operator<(const String &, const String &);
friend bool operator>(const String &, const String &);
friend bool operator<=(const String &, const String &);
friend bool operator>=(const String &, const String &);
friend std::ostream &operator<<(std::ostream &os, const String &s);
friend std::istream &operator>>(std::istream &is, String &s);
private:
char * _pstr;
};
bool operator==(const String &lhs, const String &rhs)
{
return !strcmp(lhs._pstr, rhs._pstr);
}
bool operator!=(const String &lhs, const String &rhs)
{
return strcmp(lhs._pstr, rhs._pstr);
}
bool operator<(const String &lhs, const String &rhs)
{
return strcmp(lhs._pstr, rhs._pstr) < 0;
}
bool operator>(const String &lhs, const String &rhs)
{
return strcmp(lhs._pstr, rhs._pstr) > 0;
}
bool operator<=(const String &lhs, const String &rhs)
{
return strcmp(lhs._pstr, rhs._pstr) <= 0;
}
bool operator>=(const String &lhs, const String &rhs)
{
return strcmp(lhs._pstr, rhs._pstr) >= 0;
}
std::ostream &operator<<(std::ostream &os, const String &rhs)
{
if(rhs._pstr)
{
os << rhs._pstr;
}
return os;
}
//String s1("hello")
//cin >> s1;
std::istream &operator>>(std::istream &is, String &rhs)
{
if(rhs._pstr)
{
delete [] rhs._pstr;
rhs._pstr = nullptr;
}
//动态获取从键盘输入数据的长度
vector<char> buffer;
char ch;
while((ch = is.get()) != '\n')
{
buffer.push_back(ch);
}
rhs._pstr = new char[buffer.size() + 1]();
strncpy(rhs._pstr, &buffer[0], buffer.size());
return is;
}
String operator+(const String &lhs, const String &rhs)
{
cout << "String operator+(const String &, const String &)" << endl;
String tmp(lhs);
tmp += rhs;
return tmp;
}
String operator+(const String &lhs, const char *pstr)
{
cout << "String operator+(const String &, const char *)"<< endl;
String tmp(lhs);
tmp += pstr;
return tmp;
}
String operator+(const char *pstr, const String &rhs)
{
cout << "String operator+(const char*, const String &)" << endl;
String tmp(pstr);
tmp += rhs;
return tmp;
}
void test()
{
String s1;
/* std::cin >> s1; */
cout << "s1 = " << s1 << endl;
cout << endl << endl;
String s2 = "hello";
cout << "s2 = " << s2 << endl;
cout << endl << "1111" << endl;
s2 = "world"; //error
cout << "s2 = " << s2 << endl;
cout << endl << endl;
s2 = s2;
cout << "s2 = " << s2 << endl;
cout << endl << endl;
String s3 = "wuhan";
s3 += " welcome to string word";
cout << "s3 = " << s3 << endl;
}
int main(int argc, char **argv)
{
test();
return 0;
}