自定义String类

String类:
1.无参数、带参数、对象浅拷贝、对象深拷贝等构造函数
2.运算符= += == != > < >= <=、输入输出流istream ostream的重载


//实现Stinrg 类中 构造函数、运算符= += == != > < >= <=、输入输出流istream ostream的重载

#include <iostream>
//#include <String>    //不加入此头文件
#include <string.h>
#include <stdio.h>
using std::cout;
using std::cin;
using std::endl;

class String {
public:
    String();
    String(const char *);
    String(const String&);
    ~String();
    String &operator=(const String &);
    String &operator=(const char *);

    String &operator+=(const String &);
    String &operator+=(const char *);

    char &operator[](std::size_t index);
    const char &operator[](std::size_t index) const;          //const对象只能调用const成员函数;普通对象均能调用

    std::size_t size() const;
    const char* c_str() const;

    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 &, const String &);
    friend std::istream &operator>>(std::istream &, String &);

private:
    char * _pstr;
};

String operator+(const String &, const String &);
String operator+(const String &, const char *);
String operator+(const char *, const String &);

String::String()
:_pstr(new char[1])
{
    *_pstr='\0';
}

String::String(const char* pstr)
:_pstr(new char[strlen(pstr)+1])
{
    strcpy(_pstr,pstr);
}

String::String(const String & rhs)
:_pstr(new char[strlen(rhs._pstr)+1])
{
    strcpy(_pstr,rhs._pstr);
}

String::~String(){
    delete [] _pstr;
}

String & String::operator=(const String &rhs){
    if(this != &rhs){        //避免自复制问题 左右均为指针
        delete [] _pstr;
        _pstr=new char [strlen(rhs._pstr)+1];
        strcpy(_pstr,rhs._pstr);
    }
    return *this;
}

String & String::operator=(const char * pstr){
    if(!strcmp(this->_pstr,pstr)){         //判断字符串内容是否相同;pstr在文字常量区,_pstr在栈区,首地址肯定不相同
        delete [] _pstr;
        _pstr=new char [strlen(pstr)+1];
        strcpy(_pstr,pstr);
    }
    return *this;
}

String & String::operator+=(const String& rhs){
    int need_length=strlen(this->_pstr)+strlen(rhs._pstr)+1;
    char *temp=new char [strlen(_pstr)+1];
    strcpy(temp,_pstr);
    delete [] _pstr;
    _pstr = new char [need_length];
    strcpy(_pstr,temp);
    delete [] temp;
    strcat(_pstr,rhs._pstr);
    return *this;
}

String & String::operator+=(const char* pstr){
    int need_length=strlen(this->_pstr)+strlen(pstr)+1;
    char *temp=new char [strlen(_pstr)+1];
    strcpy(temp,_pstr);
    delete [] _pstr;
    _pstr = new char [need_length];
    strcpy(_pstr,temp);
    delete [] temp;
    strcat(_pstr,pstr);
    return *this;
}

char & String::operator[](std::size_t index){
    static char nullchar = '\0';
    if(index>=0 && index<strlen(_pstr)){
        return _pstr[index];
    }
    return nullchar;
    //return '\0';     //引用不要返回局部变量
}

const char & String::operator[](std::size_t index) const{          //const对象只能调用const成员函数;普通对象均能调用
    static char nullchar = '\0';
    if(index>=0 && index<strlen(_pstr)){
        return _pstr[index];
    }
    return nullchar;
}

std::size_t String::size() const{
    if(*(this->_pstr)=='\0') return 0;
    return strlen(this->_pstr);
}

const char* String::c_str() const{
    return _pstr;                    //返回char* 
}

//A类的友元函数 能直接访问A类的private成员变量

bool operator==(const String &left, const String &right){
    return !strcmp(left._pstr,right._pstr);
}

bool operator!=(const String &left, const String &right){
    return strcmp(left._pstr,right._pstr);
}

bool operator<(const String &left, const String &right){
    return strcmp(left._pstr,right._pstr)<0?true:false;
}

bool operator>(const String &left, const String &right){
    return strcmp(left._pstr,right._pstr)>0?true:false;
}

bool operator<=(const String &left, const String &right){
    return strcmp(left._pstr,right._pstr)<=0?true:false;
}

bool operator>=(const String &left, const String &right){
    return strcmp(left._pstr,right._pstr)>=0?true:false;
}

std::ostream &operator<<(std::ostream &os, const String &rhs){       //对于String类 输出流重载
    os << rhs._pstr<<endl;
    return os;
}

std::istream &operator>>(std::istream &is, String &rhs){
    delete [] rhs._pstr;
    rhs._pstr=new char[256]{0};
    is >> rhs._pstr;          
    return is;
}


    String operator+(const String &, const String &);
    String operator+(const String &, const char *);
    String operator+(const char *, const String &);
String operator+(const String &left, const String &right){   //String += String
    String temp1(left);
    String temp2(right);    //初始化两个实例
    temp1 +=temp2;
    return temp1;           //返回String 对象
}
String operator+(const String &left, const char *right){    //String += char*
    String temp1(left);
    //String temp2(right);    
    temp1 +=right;
    return temp1;           //返回String 对象
}
String operator+(const char *left, const String &right){     //要求 left在前
    String temp1(left);
    String temp2(right);    
    temp1 +=temp2;
    return temp1;           //返回String 对象
}   

int main(int argc,char ** argv){
    //**********************构造函数测试
    String str1;
    String str2("hello,world");
    String str3(str2);
    cout<<str1;
    cout<<str2;
    cout<<str3;
    cout<< String("---------------------");

    //***********************  = 运算符测试
    const char *pstr="hello,world,cui";
    String str4=pstr;
    String str5=str4;
    cout<<str4;
    cout<<str5;
    cout<< String("---------------------");

    //********************** += 运算符测试
    String str6("hello,");
    str6 +=str6;
    cout<<str6;
    str6 += "cuixuange";
    cout<<str6;
    cout<< String("---------------------");

    //********************** [] 运算符测试
    String str7("Hello");
    const String str8("CUIXUANGE");
    cout<<str7[0]<<endl;             //单个字符输出不会调用 重载的string输出;  额外加上换行符
    cout<<str8[8]<<endl;
    cout<< String("---------------------");

    //********************** size c_str 函数测试
    cout << "size():"<<str8.size()<<endl;
    cout<<str8.c_str()<<endl;
    cout<< String("---------------------");

    //********************** == != > < >= <= 运算符测试
    String str9="hello";
    String str10="Hello";
    cout<<"NOTE: true is 1 ; false is 0"<<endl;
    cout<<"==? "<<(str9==str10)<<endl;
    cout<<"!=? "<<(str9!=str10)<<endl;
    cout<<"> ? "<<(str9> str10)<<endl;
    cout<<"< ? "<<(str9< str10)<<endl;
    cout<<">=? "<<(str9>=str10)<<endl;
    cout<<"<=? "<<(str9<=str10)<<endl;
    cout<< String("---------------------");

    //********************** << >>运算符测试 
    String str11;
    cout<<"input something...."<<endl;
    cin>>str11;
    cout<<"cin:"<<str11;
    cout<< String("---------------------");   //测试 << 流

    //********************** + 运算符测试 
    String str12;
    String str13("hello");
    String str14(",world");
    const char *pstr2=",world";
    str12 = str13 + str14;
    cout<<"string + string:       "<<str12;
    str12 =str13 + pstr2;
    cout<<"string + const char*: " << str12;
    str12 = pstr2 + str13 ;
    cout<<"const char* + string: " << str12;

    return 0;
}
/*
1.友元函数
有三种类型 自由函数,其他类的成员函数, 友元类 。 被定义的友元内容 能够直接访问当前类的private 私有成员变量

2.运算符重载原则
操作数必须为用户自定义的类、枚举类;优先性、结合性是固定的;一般不重载 && || 等逻辑运算符

3.不能重载的运算符
成员访问符 .     成员指针访问运算符 .*    域运算符 ::   长度运算符 sizeof      条件运算符号 ?:

4.运算符重载形式
自由函数重载operator  例如 + ,-。返回一个新的实例 
友元函数重载operator   能访问类私有成员
成员函数重载operator  例如 ++ += 。返回一个实例的引用,因为左值一般已经存在,避免返回新实例 浅拷贝出错、 也提高了效率

5.前置++ 后置++区别
前置++ 返回this的引用   ;   后置++ 返回this的复制对象
前置++ 在容器的迭代器中使用能提高使用效率
前置++和后置++参数和返回值类型不同
后置++有一个(int)类型参数,调用时编译器传递一个0作为该(int)的值

//  http://blog.csdn.net/randyjiawenjie/article/details/6747720
    返回类型不同
    形参不同
    效率不同
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值