String.h
#include "String.h"
#include <cstring>
namespace TCPL
{
String::String()
{
rep = new Srep(0, "");
}
String::String(const char *s)
{
rep = new Srep(strlen(s), s);
}
String::String(const TCPL::String &x)
{
x.rep->n++;
rep = x.rep;
}
String& String::operator=(const char* s)
{
if(rep->n == 1)
rep->assign(strlen(s), s);
else {
rep->n--;
rep = new Srep(strlen(s), s);
}
return *this;
}
String& String::operator =(const TCPL::String & x)
{
x.rep->n++;
if(--rep->n == 0) delete rep;
rep = x.rep;
return *this;
}
String::~String()
{
if(--rep->n == 0)
{
delete rep;
}
}
std::ostream& operator<<(std::ostream& os, const TCPL::String& x)
{
os << x.rep->s;
return os;
}
void String::check(int i) const { if( i < 0 || rep->sz <= i) throw Range(); }
char String::read(int i) const { return rep->s[i]; }
void String::write(int i, char c) { rep = rep->get_own_copy(); rep->s[i] = c; }
String::Cref String::operator[](int i) { check(i); return Cref(*this, i); }
char String::operator[](int i) const { check(i); return rep->s[i]; }
int String::size() const { return rep->sz; }
}
String.cpp
#ifndef _The_CPP_Programming_language_Chapter11_String
#include <iostream>
namespace TCPL
{
class String
{
struct Srep;
Srep *rep;
public:
class Cref;
class Range{ };
String();
String(const char *);
String(const String &);
String& operator=(const String &);
String& operator=(const char *);
~String();
friend std::ostream& operator<<(std::ostream&, const String&);
void check(int i) const;
char read(int i) const;
void write(int i, char c);
Cref operator[](int i);
char operator[](int i) const;
int size() const;
};
struct String::Srep {
char *s;
int sz;
int n; // 引用次数
Srep(int nsz, const char *p)
{
n = 1;
sz = nsz;
s = new char[sz+1];
strcpy(s, p);
}
~Srep() { delete[] s; }
Srep* get_own_copy( )
{
if(n == 1)
return this;
n--;
return new Srep(sz, s);
}
void assign(int nsz, const char* p)
{
if( sz != nsz)
{
delete[] s;
sz = nsz;
s = new char[sz+1];
}
strcpy(s, p);
}
private:
// 防止复制~!
Srep(const Srep&);
Srep& operator=(const Srep&);
};
class String::Cref
{
friend class String;
String &s;
int i;
Cref(String & ss, int ii): s(ss), i(ii){}
public:
operator char() const { return s.read(i); }
void operator =(char c) { s.write(i, c); }
};
}
#endif
test.cpp
#include "String.h"
int main(char *argv[], int argn)
{
using TCPL::String;
String str = "hello, world!";
const String str2(str);
std::cout << str << std::endl;
str[0] = 'c';
std::cout << str << std::endl;
return 0;
}
运行截图: