zoukankan      html  css  js  c++  java
  • operator[],识别读操作和写操作


    #include<iostream>
    #include<string.h>
    using namespace std;
    class String
    { //23种设计模式之代理模式
            class charProxy;
            public:
                    String():_pstr(new char[2])
                    {
                            cout<<"String()"<<endl;
                            initRefcount();
                    }
                    String(const char *);
                    String(const String&);
                    String& operator=(const String&);
                    ~String()
                    {
                            cout<<"~String()"<<endl;
                            decreaseRefcount();
                            if(0==useCount())
                            {
                                    delete []_pstr;
                            }
                    }
                    int useCount()
                    {
                            return _pstr[strlen(_pstr)+1];
                    }
                    charProxy operator[](int index); //区分写操作,这里要返回一个临时对象就不能是一个引用了
                    // char& operator[](int idx)const;  //区分读操作,必须加const关键字,不然和前面函数构成重载
            private:
                    char* _pstr;
                    void initRefcount()
                    {
                            _pstr[strlen(_pstr)+1] = 1;
                    }
                    void increaseRefcount()
                    {
                            ++_pstr[strlen(_pstr)+1];
                    }
                    void decreaseRefcount()
                    {
                            --_pstr[strlen(_pstr)+1];
                    }
                    class charProxy
                    {
                            public:  //这些函数一定要是公有
                                    charProxy(String& str,int index):_str(str),_index(index)
                                    {
                                            cout<<"charProxy(String&,int)"<<endl;
                                    }
                                    char& operator=(char ch);         //嵌套类里面,也不能返回对象引用;因为嵌套类对象都是临时的
                                    operator char()
                                    { //类型转换函数,由Charproxy转向char
                                            cout<<"operator char()"<<endl;
                                            return _str._pstr[_index];
                                    }
                            private:
                                    String& _str;
                                    int _index;
                    };
                    friend ostream& operator<<(ostream&,const String&);
                    friend istream& operator>>(istream&,String&);
    };
    #if 0
    //operator[]()不能区分读操作还是写操作
    char & String::operator[](int idx)const       //不能区分读写操作,废弃
    {
            cout<<"operator [](int)const"<<endl;
            return _pstr[idx];
    }
    #endif
    String::String(const char* tmp)
    {
            cout<<"String(const char*)"<<endl;
            _pstr = new char[strlen(tmp)+2];
            strcpy(_pstr,tmp);
            initRefcount();  //引用计数设置为1
    }
    String::String(const String& lhs)
    {
            cout<<"String(const String&)"<<endl;
            _pstr = lhs._pstr;
            increaseRefcount();
    }
    String& String::operator=(const String& lhs)
    {
            cout<<"String& operator=(const String&)"<<endl;
            decreaseRefcount();
            if(0==useCount())
            {
                    delete []_pstr;
            }
            _pstr = lhs._pstr; // 浅拷贝
            increaseRefcount();
            return *this; 
    }
    ostream& operator<<(ostream& os,const String& rhs)
    {
            cout<<"ostream& operator<<(ostream& os,const String&)"<<endl;
            os<<rhs._pstr<<endl;
            return os;
    }
    istream& operator>>(istream& is,String& s)
    {
            cout<<"istream& operator>>(istream&,String&)"<<endl;
            is>>s._pstr;
            return is;
    }

    String::charProxy String::operator[](int index)
    {
            cout<<"charProxy operator[](int)"<<endl;
            return charProxy(*this,index);     //返回临时嵌套类对象
    }
    char& String::charProxy::operator=(char ch)
    {
            cout<<"char& operator=(char)"<<endl;
            if(_index>=0&&_index<strlen(_str._pstr))
            {
                    if(1==_str.useCount())  //当对象没有共享内存时
                    {
                            _str._pstr[_index] = ch;  //修改
                            return _str._pstr[_index];
                    }
                    else
                    {
                            _str.decreaseRefcount();  //有共享内存
                            char* _strtmp = new char[strlen(_str._pstr)+2];
                            strcpy(_strtmp,_str._pstr);
                            _str = _strtmp;  //这里调用了构造函数和赋值构造函数,操作完之后调用析构函数
                            _str[_index] = ch;  //这里再次调动[]重载函数,进行修改
                            _str.initRefcount();
                            return _str._pstr[_index];
                    }
            }
    }
    int main()
    {
            String s1("hello,world");
            String s2(s1);
            cout<<"读操作:"<<s1[1]<<endl;
            cout<<s1.useCount()<<endl;
            cout<<"--------------------------"<<endl;
            cout<<"写操作:"<<endl;
            s1[1] = 'm';
            cout<<"--------------------------"<<endl;
            cout<<s1[1]<<endl;
            cout<<s1.useCount()<<endl;
            return 0;
    }


    //String(const char*)
    //String(const String&)
    //charProxy operator[](int)
    //charProxy(String&,int)
    //operator char()
    //读操作:e
    //2
    //--------------------------
    //写操作:
    //charProxy operator[](int)
    //charProxy(String&,int)
    //char& operator=(char)
    //String(const char*)
    //String& operator=(const String&)
    //~String()
    //charProxy operator[](int)
    //charProxy(String&,int)
    //char& operator=(char)
    //--------------------------
    //charProxy operator[](int)
    //charProxy(String&,int)
    //operator char()
    //m
    //1
    //~String()
    //~String()


    这里要识别[]操作只能借助嵌套类来底层实现,因为不可能在String类中重写=运算符;所以当遇到[]操作符的时候就转化成CharProxy的对象,必须传引用对其本身操作,在这个类中就可以重写=运算符来区分读和写,因为这里的=我们后面不会再做其他用处只是区分读写;所以这里分三步:
    重写[]运算符
    先转换为嵌套类对象
    重写=,区分s[]和是s[]=
    改:

    读:

    读的时候cout不能输出CharProxy对象,除非重载;采用类型转换比较方便,会根据需要自动转换


  • 相关阅读:
    异常处理
    弹出对话框
    ef——存储过程
    事务
    linq——常用方法
    Linq
    asp get与post获取的区别
    Web服务的调用
    AJAX控件——多层弹出Accordion
    数据绑定
  • 原文地址:https://www.cnblogs.com/meihao1203/p/8949516.html
Copyright © 2011-2022 走看看