重載箭頭操作符

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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章