#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; }