智能指针

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


posted @ 2011-01-13 20:24  Cranny  阅读(256)  评论(0编辑  收藏  举报