c++ 重载的成员访问操作符

来源:互联网 发布:新淘宝直通车怎么开通 编辑:程序博客网 时间:2024/05/26 08:42

箭头操作符(必须定义为类成员函数)和解引用操作符(不要求定义为成员)常用在实现智能指针的类中。

下面是c++ primer中第14.6节的一个比较完整的测试例子:

#include <iostream>#include <cstdlib>using namespace std;class ScreenPtr;class Screen {    public:        //此种构造方法能处理传递过来的s,完成对屏幕的初始化        Screen(int x, int y, const string &s):cursor(0),height(x),width(y) {//初始化屏幕和当前光标的位置            contents.assign(x*y, 'g');            if(s.size() != 0) contents.replace(0, s.size(), s);        }        char get() {return contents[cursor];}        //添加了容错处理        Screen& move(int x, int y) {            if(x >= height || y >= width) {                cerr << "unvaliable row or column" << endl;                throw EXIT_FAILURE;            }            cursor = x*width + y;            return *this;//返回对自身的引用        }        Screen& set(char c) {            contents[cursor] = c;            return *this;        }        //使字符串分行显示        //两个重载函数,分别有const对象和非const对象调用。并且由于两个函数的函数体一样,故抽出来作为一个函数        void display(ostream &os) {            do_display(os);        }        const void display(ostream &os) const {            do_display(os);        }    private:        string contents;        string::size_type cursor;        string::size_type height, width;        inline const void do_display(ostream &os) const{            string::size_type index = 0;            while(index != contents.size()) {                if(index % this->width == 0) os << endl;                os << contents[index];                index ++;            }            os << endl;        }};//private类, 智能指针class U_Ptr {    friend class ScreenPtr;    U_Ptr(Screen *p):ip(p), use(1){}    Screen *ip;    size_t use;    ~U_Ptr() {delete ip;}};//考虑:为什么要用智能指针?//因为重载了成员访问符,可能存在指向Screen类的很多指针,为了避免操作过程中出现悬垂指针和方便的正确的管理指针,所以要对指针进行管理。//考虑:为什么要重载成员访问符?//因为普通的成员访问符已经不能满足要求。class ScreenPtr {    friend inline bool operator==(const ScreenPtr &sc, const ScreenPtr &scrp);    friend inline bool operator!=(const ScreenPtr &sc, const ScreenPtr &scrp);    public:        //没有默认的构造函数        ScreenPtr(Screen *scr):ptr(new U_Ptr(new Screen(*scr))) {}        //拷贝构造函数        ScreenPtr(const ScreenPtr &scrp):ptr(scrp.ptr) {            ++scrp.ptr->use;        }        //重载的赋值操作符        ScreenPtr& operator=(const ScreenPtr& scrp) {            if(0 == --ptr->use) delete ptr;            ++scrp.ptr->use;            ptr = scrp.ptr;            return *this;        }        //重载成员访问符        Screen& operator*() {return *ptr->ip;}        Screen* operator->() {return ptr->ip;}        const Screen& operator*() const {return *ptr->ip;}        const Screen* operator->() const {return ptr->ip;}        //析构函数        ~ScreenPtr() {            if(0 == --ptr->use) delete ptr;        }    private:        U_Ptr *ptr;};//==,!=一般重载为非成员函数// 重载相等操作符inline bool operator==(const ScreenPtr &sc, const ScreenPtr &scrp) {    return sc.ptr == scrp.ptr;}//重载不相等操作符inline bool operator!=(const ScreenPtr &sc, const ScreenPtr &scrp) {    return !(sc == scrp);}int main(){    string str = "aab";    Screen myScreen(5,5,str);    ScreenPtr sc(&myScreen);    ScreenPtr sc1 = sc;    sc->display(cout);//理解重载箭头操作符的执行过程(c++ primer第14.6.4节(p445)(第四版))    return 0;}
总结:重载的成员访问操作符的函数就像是递归函数一样。不断的调用,直到达到目的为止。