书上的例题,还没做完,Srep类是实际的容器,Cref是帮助String实现下标的操作。
把String类的实现分解,这些类可以被限制在String的空间。可能显得比较麻烦,我觉得有些意义的。
String.h
[CODE]#ifndef MYSTRING_H
#define MYSTRING_H
#include <cstring>
#include <iostream>
using namespace std;
class String
{
struct Srep
{
char *s;
int sz;
int n; //reference counter
Srep(int nsz, const char *p):sz(nsz),n(1)
{
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);
}
};
Srep *rep;
public:
class Cref
{
friend class String;
String &str;
int i;
Cref(String &ss, int ii): str(ss),i(ii) {}
public:
void operator=(const char ch) { str.write(i, ch); }
operator char() { return str.read(i); }
};
class Range {};
String();
String(const char *p);
String(const String &s);
~String();
void check(int i)const { if( i<0 || i>=rep->sz ) throw Range(); }
char read(int i) { return rep->s[i]; }
void write(int i, char ch) { rep = rep->get_own_copy(); rep->s[i]=ch; }
Cref operator[](int i) { check(i); return Cref(*this, i); }
char operator[](int i)const { check(i); return rep->s[i]; }
String& String::operator=( const String& );
String& String::operator=( const char* );
String& operator+=( const String& );
String& operator+=( const char* );
friend ostream& operator<<(ostream&, const String&);
friend istream& operator>>(istream&, String&);
friend bool operator==(const String &x, const String &y)
{ return strcmp(x.rep->s, y.rep->s) == 0; }
friend bool operator==(const String &x, const char *p)
{ return strcmp(x.rep->s, p) == 0; }
friend bool operator!=(const String &x, const String &y)
{ return strcmp(x.rep->s, y.rep->s) != 0; }
friend bool operator!=(const String &x, const char *p)
{ return strcmp(x.rep->s, p) != 0; }
friend bool operator>(const String &x, const String &y)
{ return strcmp(x.rep->s, y.rep->s) > 0; }
friend bool operator<(const String &x, const String &y)
{ return strcmp(x.rep->s, y.rep->s) < 0; }
};
String operator+(const String&, const String&);
String operator+(const String&, const char*);
String operator+(const char*, const String&);
#endif
[/CODE]
String.cpp
[CODE]#include "String.h"
String::String()
{
rep = new Srep(0, "");
}
String::String(const String &x)
{
rep = x.rep;
rep->n++;
}
String& String::operator=(const String &x)
{
(x.rep->n)++;
if(--(rep->n) == 0) delete rep;
rep = x.rep;
return *this;
}
String::~String()
{
if(--(rep->n) == 0) delete rep;
}
String::String(const char *p)
{
rep = new Srep(strlen(p), p);
}
String& String::operator=(const char *p)
{
if(rep->n == 1)
rep->assign(strlen(p), p);
else
{
rep->n--;
rep = new Srep(strlen(p), p);
}
return *this;
}
String& String::operator+=(const String &x)
{
Srep *tmp = new Srep(rep->sz + x.rep->sz, rep->s);
strcpy( (tmp->s + rep->sz), x.rep->s);
if(--(rep->n) == 0)
delete rep;
rep = tmp;
return *this;
}
String& String::operator+=(const char *p)
{
Srep *tmp = new Srep( (rep->sz + strlen(p)), rep->s );
strcpy( (tmp->s + rep->sz), p);
if(--(rep->n) == 0)
delete rep;
rep = tmp;
return *this;
}
istream& operator>>(istream &in, String &x)
{
char tmp[100];
in.get(tmp, 100);
if(in)
x = tmp;
in.get(tmp, 100);
while(in)
{
x += tmp;
in.get(tmp, 100);
}
in.clear();
in.sync();
return in;
}
ostream& operator<<(ostream &out, const String &x)
{
if(x.rep->sz > 0)
out<<x.rep->s;
return out;
}
String operator+(const String &x, const String &y)
{
String tmp(x);
return tmp += y;
}
String operator+(const String &x, const char *p)
{
String tmp(x);
return tmp += p;
}
inline String operator+(const char *p, const String &x)
{
return x + p;
}[/CODE]
main.cpp
[CODE]#include <iostream>
#include "String.h"
using namespace std;
String f(String a, String b)
{
a[2] = 'x';
char c = b[3];
cout<<a<<' '<<b<<' '<<c<<endl;
return b;
}
int main(int argc, char *argv[])
{
String x, y;
cout<<"please enter two strings\n";
cin>>x>>y;
cout<<"input : "<<x<<' '<<y<<endl;
String z = x;
y = f(x, y);
if(x != z) cout<<"x corrupted\n";
x[0] = '!';
if(x == z) cout<<"write failed\n";
cout<<"exit : "<<x<<' '<<y<<' '<<z<<endl;
cout<<x+y<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}[/CODE]