重载箭头操作符

C++primer中重载箭头操作符部分看得有点云里雾里的。经过反复测试,有了点眉目,为了避免自己忘掉,记下现在的心得。因为自己比较懒,就直接把代码和注释贴过来。

////////////////////////////   -----NoName.h---- //////////////////////////////////////////////
#pragma once
#include"ScreenPtr.h"

class NoName
{
public:
 NoName(Screen* p):m_sp(new ScreenPtr(p))
 {}
 ~NoName(void)
 {}
private:
 ScreenPtr* m_sp;
public:

 ScreenPtr operator->(void)
 {
  return *m_sp;
 }
 const ScreenPtr operator->(void) const
 {
  return *m_sp;
 }
};

////////////////////////////   -----ScrPtr.h---- //////////////////////////////////////////////
#pragma once
#include"Screen.h"

class ScrPtr
{
 friend class ScreenPtr;

 ScrPtr(Screen* p):sp(p), count(1)
 {}
 ~ScrPtr(void)
 {
  delete sp;
 }

 Screen* sp;
 size_t count;
};

////////////////////////////   -----Screen.h---- //////////////////////////////////////////////
#pragma once
#include<iostream>
using namespace std;

class Screen
{
public:
 Screen(void):cursor(0), height(0), width(0)
 {}
 ~Screen(void)
 {}

 typedef string::size_type index;
private:
 string contents;
 index cursor;
 index height, width;
public:
 friend ostream& operator<<(ostream& os, const Screen& scr)
 {
  os << scr.cursor << '/t' << scr.height << '/t' << scr.width;
  return os;
 }

 index get_cursor(void)
 {
  return cursor;
 }
};

////////////////////////////   -----ScreenPtr.h---- //////////////////////////////////////////////
#pragma once
#include"ScrPtr.h"

class ScreenPtr
{
public:
 ScreenPtr(Screen* p);
 ~ScreenPtr(void);
private:
 ScrPtr* m_sptr;
public:
 ScreenPtr(const ScreenPtr& orig);
 ScreenPtr& operator=(ScreenPtr& rhs);

 Screen& operator*(void);
 const Screen& operator*(void) const;
 Screen* operator->(void);
 const Screen* operator->(void) const;
};

 

#include "ScreenPtr.h"

ScreenPtr::ScreenPtr(Screen* p):m_sptr(new ScrPtr(p))
{
}

ScreenPtr::~ScreenPtr(void)
{
 if(-- m_sptr->count == 0)
  delete m_sptr;
}

ScreenPtr::ScreenPtr(const ScreenPtr& orig):m_sptr(orig.m_sptr)
{
 ++ m_sptr->count;
}

ScreenPtr& ScreenPtr::operator=(ScreenPtr& rhs)
{
 //TODO: insert return statement here
 if(-- m_sptr->count == 0)
  delete m_sptr;
 ++ rhs.m_sptr->count;
 m_sptr = rhs.m_sptr;

 return *this;
}

////////////////////////////   -----ScreenPtr.cpp---- //////////////////////////////////////////////

#include "ScreenPtr.h"

ScreenPtr::ScreenPtr(Screen* p):m_sptr(new ScrPtr(p))
{
}

ScreenPtr::~ScreenPtr(void)
{
 if(-- m_sptr->count == 0)
  delete m_sptr;
}

ScreenPtr::ScreenPtr(const ScreenPtr& orig):m_sptr(orig.m_sptr)
{
 ++ m_sptr->count;
}

ScreenPtr& ScreenPtr::operator=(ScreenPtr& rhs)
{
 //TODO: insert return statement here
 if(-- m_sptr->count == 0)
  delete m_sptr;
 ++ rhs.m_sptr->count;
 m_sptr = rhs.m_sptr;

 return *this;
}
Screen& ScreenPtr::operator*(void)
{
 //TODO: insert return statement here
 return *m_sptr->sp;
}

const Screen& ScreenPtr::operator*(void) const
{
 //TODO: insert return statement here
 return *m_sptr->sp;
}
Screen* ScreenPtr::operator->(void)
{
 return m_sptr->sp;
}

const Screen* ScreenPtr::operator->(void) const
{
 return m_sptr->sp;
}


////////////////////////////   -----main.cpp---- //////////////////////////////////////////////
#include<iostream>
//#include"Person.h"
#include"Screen.h"
#include"ScreenPtr.h"
#include"ScrPtr.h"
#include"NoName.h"
//#include"Sales_item.h"
//#include<vector>
//#include"SmartPtr.h"
//#include"HasPtr.h"

using namespace std;

void main()
{
Screen* scr = new Screen;
 ScreenPtr pscr(scr);
 cout << *pscr << endl;

 ScreenPtr pscr2(pscr);

// cout << (pscr2.operator ->())->get_cursor() << endl; // 该行与下一行等价 // ->get_cursor() “内置”-> 操作符
            // “内置”箭头操作符作用于返回的指针
// cout << pscr2->get_cursor() << endl; // 调用“重载”->操作符
           cout << (*pscr2).get_cursor() << endl; 等价于 cout << Screen().get_cursor() << endl;

 

 

 NoName noname(scr);

 cout << noname->get_cursor() << endl; // 该行与下一行等价
 cout << ((noname.operator ->()).operator ->())->get_cursor() << endl; // 返回类型是类类型的其他对象(或该对象的引用),递归调用->操作符
}

 

 

 

 

如果将ScreenPtr类的operator->成员函数返回类型改成Screen对象,则由于Screen类没有重载operator->操作符,所有->只能作为成员函数调用,而不能递归调用。

Screen test = pscr2.operator->();      // 最末一级只能返回指针

发布了4 篇原创文章 · 获赞 3 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章