首页 > 代码库 > 关于解引用*和箭头操作符->的重载
关于解引用*和箭头操作符->的重载
这里以一个智能指针类为例,智能指针所指为一个对象。
而事实上,STL迭代器的开发均需要重载这两个操作符,上一篇文章分析STL 迭代器中除了要用到template技巧外,还需要重载技巧
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_ptr19 {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 ScreenPtr27 {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 gao44 {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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。