zoukankan      html  css  js  c++  java
  • String 类实现 以及>> <<流插入/流提取运算符重载

    简单版的String类,旨在说明>> <<重载

    #include <iostream>
    //#include <cstring>//包含char*的字符串处理函数
    using namespace std;
    
    class String
    {
    public:
        String(){p=NULL;}
        String(char *str);
        void diaplay();
        friend bool operator>(String &str1,String &str2);//重载>操作符
        friend ostream & operator <<(ostream&,String &str);
        friend istream & operator >>(istream&,String &str);
    private:
        char *p;
    };
    String::String(char *str)
    {
        p=str;
    }
    void String::diaplay()
    {
        cout<<p;
    }
    bool operator>(String &str1,String &str2)
    {
        if (strcmp(str1.p,str2.p)>0)
        {
            return true;
        }
        else return false;
    }
    ostream& operator <<(ostream& output,String &str)
    {
        output<<str.p;
        return output;
    }
    istream& operator >>(istream& input,String &str)
    {
        //input>>str.p;//没有分配空间,无法读入。
        str.p=new char[256];
        input>>str.p;
        return input;//
    //     char q[256];  
    //     input>>q;  
    //     //p.length =strlen(q);  
    //     str.p=new char[strlen(q)+1];  
    //     strcpy(str.p,q);  
    //     return input;
    
    }
    int main()
    {
        String str1("Hello,pig!"),str2;
        cin>>str2;
        str1.diaplay();
        bool b=str1>str2;
        cout<<'
    '<<b<<endl;
        cout<<str2<<endl;
    }

    重载>> <<函数只能作为类的类的友元函数,其形式如下:

    istream& operator >>(istream& ,自定义类 &);

    ostream& operator <<(ostream& ,自定义类 &); 

    重载运算法作为类成员函数还是类友元函数区别:

    1 作为类成员函数必须满足运算表达式第一个参数是一个类对象,而且返回值与该对象同类型。

    故一般将单目操作符重载为成员函数,双目操作符重载为友元函数。

    String 类较完整实现:

    #include <iostream>
    //#include <cstring>//包含char*的字符串处理函数
    using namespace std;
    
    class String
    {
    public:
        String(){p=NULL;len=0;}
        String(int);
        String(char *str);
        String (String&);
        ~String(){delete[] p;}
        void Clear();//清空本串
        int mystrlen();
        bool IsEmpty();//判断本串是否为空
        String Substr(int index,int count);//从index开始提取count个字符的字串
        int Find(char c,int start);//从下标start开始找到c后,返回字符c 在本串的下标
        char & operator [](int i);//重载[]操作符
        operator char *();//将String类对象转换为普通字符串
    
        friend bool operator>(String &str1,String &str2);//重载>操作符
        friend ostream & operator <<(ostream&,String &str);
        friend istream & operator >>(istream&,String &str);
    private:
        char *p;//字符串指针
        int len;//字符串长度,不包含最后的
    };
    
    String::String(int length)
    {
        len=length;
        p=new char[length+1];
    }
    String::String(char *str)
    {
        if (str==NULL)
        {
            len=0;
            p=NULL;
        }
        else
        {
            len=strlen(str);
            p=new char[len+1];
            strcpy(p,str);//深拷贝
        }
        //p=str;//只写这个是浅拷贝,只拷贝了指针
    }
    String::String(String &other)
    {
        len=other.len;
        p=new char[len+1];
        strcpy(p,other.p);
    }
    bool String::IsEmpty()
    {
        return (!this->len);
    }
    
    void String::Clear()
    {
        if (!IsEmpty())
        {
            delete[]p;
            len=0;
        }
    }
    int String::mystrlen()
    {
        return len;
    }
    int String::Find(char c,int start)
    {
         int i;
        if (start>len) cout<<"超出范围"<<endl;
        //return NULL;
        else
            {
                for (i =start;i<len;++i)
                {
                    if (p[i]==c) break;
                 }
                return i;
        
              }
    }
    String String::Substr(int index,int count)
    {
        
        if (index+count>len) cout<<"超出范围"<<endl;
        else
        {
            String str(count);
            str.len=count;
            for (int i=0;i<count;i++,index++)
                str.p[i]=p[index];
    
                str.p[count]='';
                return str;
        }
        
    }
    char & String::operator[](int i)
    {
        if (i<0||i>len-1)
        {
            cout<<"越界"<<endl;
        }
        else
        {
            return p[i];
        }
    }
    //类型转换
    String::operator char *()
    {
        return (char *)p;
    }
    
    bool operator>(String &str1,String &str2)
    {
        if (strcmp(str1.p,str2.p)>0)
        {
            return true;
        }
        else return false;
    }
    ostream& operator <<(ostream& output,String &str)
    {
        output<<str.p;
        return output;
    }
    istream& operator >>(istream& input,String &str)
    {
        //input>>str.p;//没有分配空间,无法读入。
        str.p=new char[256];
        input>>str.p;
        return input;//
        //或者:
    //     char q[256];  
    //     input>>q;    
    //     str.p=new char[strlen(q)+1];  
    //     strcpy(str.p,q);  
    //     return input;
    
    }
    int main()
    {
        String str3("hello");  
        int pos;  
        cout<<"
    测试Find功能"<<endl;  
        pos = str3.Find('e',0);  
        cout<<str3<<endl;  
        cout<<pos<<endl;  
         
        cout<<"
    测试Substr功能"<<endl;  
        cout<<str3.Substr(1,2)<<endl;  
          
        cout<<"
    测试重载<< >>功能"<<endl;  
        String c;  
        cout<<"请输入一段字符串"<<endl;  
        cin>>c;  
        cout<<c<<endl;  
         
        cout<<"测试字符串C函数的应用"<<endl;  
        String f(40);  
        char *e = " this is a test";  
        char g[50]="hahahhah";
        strcpy(f,e); //隐含执行了默认类型转换(char *)f; 
        cout<<f<<endl;  
        strcat(g,f);  
        cout<<g<<endl; 
    
        cout<<"
    测试IsEmpty _strlen功能"<<endl;  
        String d("tihs is a test");  
        if(d.IsEmpty())  
            cout<<"d 是空字符串"<<endl;  
        else  
            cout<<"d 非空字符串 	长度:"<<d.mystrlen()<<endl;  
          
        return 0;  
    
    }

    注意:C++标准库中string类构造函数是浅拷贝,

     string a="hello";
     string b(a);
     cout<<(void *)a[2]<<endl;
     cout<<(void *)b[2]<<endl; 地址形同


    注意:operator char *();//将String类对象转换为普通字符串  

    是类型转换函数的定义,即该类型可以自动转换为const char*类型。

    像是隐式类型转换

    不同于重载*,重载*应写为 char operator * ();

    因为运算符重载中有几个运算符的返回值是有格式的(约定),如operator * 在重载时通常返回值是classType&或者const classType& 。
    operator const char*() const是类型转换函数的定义,即该类型可以自动转换为const char*类型。至于最后一个const,那个大家都知道是对类成员的限制(不允许更改对象的状态)
    比如我们现在自定一个一个整型(MyInt),它允许在需要使用C++语言中的int类型时将MyInt类型转换为int类型:
    class MyInt {
         public:
              operator int () const;
         private:
              int elem;
    };
    MyInt::operator int () const
    {
        return elem;
    }
    就可以在需要使用int类型时使用MyInt。
    需要记住,C++中没有返回类型的函数有3个,构造函数、析构函数、类型转换函数。

    前两个是不写返回类型函数实现中也不允许出现return语句
    最后一个则是不写返回类型,但是必须返回对应类型的值,即必须出现return语句。

    类型转换中返回类型在operator后面在括号前面,且没有参数。

    函数运算符中是类型在operator 前面

  • 相关阅读:
    ArcGis面要素空间连接,取相交面积最大者 C#
    迅雷下载器无限制版_无敏感_无限速
    redhat 6.8 配置 centos6 163 的 yum 源
    apache cgi 程序: End of script output before headers
    centos php 安装 decrypt
    url传输中+转为%2B取到变空格的问题
    快速搭建自己的搜索引擎
    ffmpeg 文件推流 rtsp和rtmp
    svn 服务器操作
    edusoho迁移
  • 原文地址:https://www.cnblogs.com/Yogurshine/p/3677799.html
Copyright © 2011-2022 走看看