#include <iostream>
#include <string>
using namespace std;
class Screen;
class ScreenPtr;
class Screen
{
public:
typedef string::size_type index;
Screen(int r = 4, int c = 3)
{
contents.resize(r * c, '#');
height = r;
width = c;
access_ctr = 0;
}
char get() const
{
return contents[cursor];
}
inline char get(index ht, index wd) const;
index get_cursor() const;
Screen& move(index r, index c);
Screen& set(char);
Screen& set(index, index, char);
Screen& display(ostream& os)
{
do_display(os);
return *this;
}
const Screen& display(ostream& os) const
{
do_display(os);
return *this;
}
private:
void do_display(ostream& os) const;
string contents;
index cursor;
index height, width;
mutable size_t access_ctr;
};
Screen& Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
Screen& Screen::move(index r, index c)
{
index row = r * width;
cursor = row + c;
return *this;
}
Screen& Screen::set(index r, index c, char x)
{
index row = r * width;
row += c;
contents[row] = x;
return *this;
}
void Screen::do_display(ostream &os) const
{
++access_ctr;
os<<contents<<"\t"<<access_ctr<<endl;
}
char Screen::get(index r, index c) const
{
index row = r * width;
return contents[row + c];
}
Screen::index Screen::get_cursor() const
{
return cursor;
}
class ScrPtr
{
friend class ScreenPtr;
Screen *sp;
size_t use;
ScrPtr(Screen *p) : sp(p), use(1){}
~ScrPtr()
{
delete sp;
}
};
class ScreenPtr
{
public:
ScreenPtr(Screen *p) : ptr(new ScrPtr(p)){}
ScreenPtr(const ScreenPtr &orig) : ptr(orig.ptr)
{
++ptr->use;
}
ScreenPtr& operator=(const ScreenPtr&);
~ScreenPtr()
{
if(--ptr->use == 0)
delete ptr;
}
Screen& operator*()
{
return *ptr->sp;
}
Screen* operator->()
{
return ptr->sp;
}
const Screen& operator*() const
{
return *ptr->sp;
}
const Screen* operator->() const
{
return ptr->sp;
}
private:
ScrPtr *ptr;
};
ScreenPtr& ScreenPtr::operator =(const ScreenPtr &rhs)
{
++rhs.ptr->use;
if(--ptr->use == 0)
delete ptr;
ptr = rhs.ptr;
return *this;
}
int main()
{
Screen myScreen(2,2);
const Screen blank(5,3);
myScreen.set(0,0,'X').display(cout);
blank.display(cout);
//无法区分指针式堆中的还是栈中的.所以不能引用上面的例子
ScreenPtr sp(new Screen());
ScreenPtr sp2(sp);
sp->set(1, 0, 'd').display(cout);
sp->display(cout);
cout<<sp->get(1,0)<<endl;
(*sp).display(cout);
ScreenPtr sp3 = sp2;
sp3->display(cout);
return 0;
}