zoukankan      html  css  js  c++  java
  • 关于解引用*和箭头操作符->的重载

    这里以一个智能指针类为例,智能指针所指为一个对象。

    而事实上,STL迭代器的开发均需要重载这两个操作符,上一篇文章分析STL 迭代器中除了要用到template技巧外,还需要重载技巧

    1.  1 #include<iostream>
       2 using namespace std;
       3 class Screen
       4 {
       5     
       6 public:
       7     friend ostream& operator<<(ostream&os, Screen &s);
       8     int action(){ return ++data; }
       9     Screen(int i = 0) :data(i){}
      10 private:
      11     int data;
      12 };
      13 ostream& operator<<(ostream&os, Screen &s)
      14 {
      15     os << s.data;
      16     return os;
      17 }
      18 class U_ptr
      19 {
      20     friend class ScreenPtr;
      21     Screen* p;
      22     size_t use;
      23     U_ptr(Screen *pp) :p(pp), use(1){}
      24     ~U_ptr(){ delete p; }
      25 };
      26 class ScreenPtr
      27 {
      28 private:
      29     U_ptr *ptr;
      30 public:
      31     ScreenPtr(Screen *p) :ptr(new U_ptr(p)){}
      32     ScreenPtr(ScreenPtr &orgi_p) :ptr(orgi_p.ptr){ ++ptr->use; }
      33     ~ScreenPtr(){ if (--ptr->use == 0)delete ptr; }
      34     Screen& operator*()
      35     {
      36         return *(ptr->p);
      37     }
      38     Screen* operator->()
      39     {
      40         return ptr->p;
      41     }
      42 };
      43 class gao
      44 {
      45 private:
      46     ScreenPtr *p;
      47 public:
      48     gao(ScreenPtr* q) :p(q){}
      49     ScreenPtr& operator->()
      50     {
      51         return *p;
      52     }
      53 };
      54 int main()
      55 {
      56     
      57     ScreenPtr ptr(new Screen(5));
      58     cout << "*操作符  " << *ptr << endl;
      59     cout << "->操作符  " << ptr->action() << endl;
      60     ScreenPtr* pp = &ptr;
      61     gao d(pp);
      62     cout << "!" << d->action() << endl;
      63     system("pause");
      64 }
     
     
    这里的代码逻辑如下:
        1. 首先定义一个简单封装的U_ptr,其实就是指向Screen的指针+一个引用计数的封装
        2. 然后定义真正的智能指针类ScreenPtr,其成员是U_ptr,
        3. 然后定义构造函数和复制构造函数(对引用计数++)
        4. 再定义析构函数,只有当--use==0时才进行析构,调用U_ptr类的析构函数
        5. 最后,为了使类ScreenPtr 具有指针类似的表现,重载operator* 和 ->
            
    *是一个一元操作符,作为成员函数故无形参,返回的是指向Screen的引用
    ->是一个一元操作符,尽管长得像二元操作符,故也无形参。
     
    这里应该格外注意,为什么其返回值是一个Screen的指针?
        可以这样理解,
          对于一个指针类型变量p,p->action()表示返回其成员       //action()为Screen类的成员函数
                  而对于我们想要重载的类ScreenPtr而言,调用->的是ScreenPtr的对象,因此这里返回一个指向Screen的指针,然后编译器会自动绑定其成员,也就是说ScreenPtr对象 sp->action()的含义为    ( sp.operator->() )->action())
           
     
    更一般的,->重载后返回值除了返回一个指针外,还可以返回一个已经重载了->操作符的类对象的引用,然后编译器递归调用重载过的->,直到有一个返回指针,如上面的类gao
     
     
     
     
     
     
  • 相关阅读:
    scrapy--Cookies
    python--signal
    python--redis
    TCP/IP 协议
    python--Wrapper
    python--inspect
    python--pexpect
    linux 特殊命令(一)
    day45 Pyhton 数据库Mysql 02
    day44 Pyhton 数据库Mysql
  • 原文地址:https://www.cnblogs.com/gaoduan/p/3903500.html
Copyright © 2011-2022 走看看