Coding之路——重新学习C++(6):一个String类

  这个String类是对运算符重载和以前知识的一个综合应用,提供了值语义、字符串读写、检查和不检查的访问、流I/O和字符串拼接等功能。

1.String类的定义

class String{
    //类型的定义
    struct Srep;        //表示能被几个同样值的String共享
    Srep *rep;
publicclass Cref;         //实现下标运算,区别对待读操作和写操作
    class Range();   //范围错误时抛出的异常

    //构造、赋值和析构函数
    String();                                         //x = "";
    String(const char*);                       //x ="abc";
    String(const String&);                    //x = other_string;
    String& operator=(const char*);
    String& operator=(const String&);
    ~String();
    
    //带检查的访问运算符
    void check(int i) const{if(i < 0 || rep->sz < i) throw Range();}
    char read(int i) const{return rep->s[i];}
    void write(int i, char c){
        rep = rep->get_own_copy(); 
        rep->s[i] =c;
    }
    Cref operator[](int i){
        check(i);
        return Cref(*this, i);
    }
    char operator[](int i) const{
        check(i);
        return rep->s[i];
    }
    int size() const{return rep->sz;}

    //其他String操作
    String& operator+=(const String&);
    String& operator+=(const char*);

    friend ostream& operator<<(ostream&, const String&);
    friend istream& operator>>(ostream&, String&);
    friend bool operator==(const String& x, const char *s){
        return strcmp(x.rep->s, 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&);    

2.Srep类:实现同样值的String类的共享

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&);
};

 3.String的复制实现

String::String(){                                 //空串为默认值
    rep = new Srep(0, "");
}

String::String(const String& x){         //拷贝构造函数
    x.rep->n++;
    rep = x.rep;
}

String::~String(){                              //析构函数
    if(--n == 0) delete rep;
}

String& operator=(const String& x){   //复制赋值
     x.rep->n++;
     if(--n == 0) delete rep;
     rep = x.rep;
     return *this;
}

String::String(const char *s){
    rep = new Srep(strlen(s), s);
}

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;
}

4.实现读和写的Cref

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);}
};

 下面是下标运算符的实例:

void f(String &s, const String &r){
    char c1 = s[1];     //c1 = s.operator[](1).operator char()
    s[1] = 'c';             //s.operator[](1).operator=('c')

    char c2 = r[1];     //c2 = r.operator[](1)
    r[1] = 'd';             //错误:给const赋值,r.operator[](1) = 'd'
}
    
原文地址:https://www.cnblogs.com/xskCoder/p/3998076.html