当前位置: 首页 > 图文教程 > 开发语言 > VC++ > C++编程杂谈之三:面向对象(续)

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 C++编程杂谈之三:面向对象(续)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 60 ::
收藏到网摘: n/a


C++编程杂谈之三:面向对象(续)

作者:xulion

下载例子源代码

 

    上一篇我们涉及了面向对象的一个基本概念--封装,封装是一个相对比较简单的概念,也很容易接受,但是很多的场合下面,仅仅是封装并不能很好的解决很多问题,考虑下面的例子:
假设我们需要设计一个对战游戏的战斗细节,在最初的版本中我们将支持一种动作--fight。假设我们有三种角色:fighter、knight和warrior,每种角色的health、hit point不同,基于封装的基本想法,我们很自然的想到对每个对象使用类的封装,首先明显的元素有2个:health、hit point,另外还有name(我们不能只有三个角色)和战斗的速度speed,方法有:hit、isalive。基于这样的想法,我们给出下面的类:
 
 class fighter{	private:	int m_iHealth;	int m_iSpeed;//为了方便,这个值使用延时值,越大表示速度越慢	const int m_iHitPoint;	char m_strName[260];	public:	fighter(const char* strName);	void hit(fighter* pfighter);	bool isAlive(); }; 
    上面的类可以清楚的抽象出我们所需要表达的数据类型之一,这里也许你已经发现了一些问题:
成员函数hit用来处理战斗事件,但是我们有不同的角色,fighter不可能只跟自己同样的对手作战,我们希望它能和任何角色战斗,当然,使用模板函数可以简单的解决这个问题。另外,我们必须去实现三个不同的类,并且这些类必须都实现这些属性和方法。即使这些问题我们都解决了,现在我们要组织两个队伍作战,我们希望使用一种群体类型来描述它们,问题是我们必须针对每一种类建立相应的群体结构,当然你可以认为3个不同的类型不是很多,完全可以应付,那么如果有一天系统升级,你需要管理上百种类型的时候,会不会头大呢?
    在C++中,继承就可以很好的解决这个问题,在C++中,继承表示的是一种IS-A关系,即派生类IS-A基类,很多现实世界中的关系可以这样来描述,如:dog is-a animal,dog是animal的派生(继承),继承产生的对象拥有父(基)对象的所有属性和行为,如animal的所有属性和行为在dog身上都会有相应的表现。在UML的描述中,这种关系被称为泛化(generalization)。一般情况下,当我们需要实现一系列相似(具有一定的共性)然而有彼此不同的类别的时候,使用继承都是很好的解决办法,例如前面的代码虽然也能够实现我们的目标,但是显然很难管理,下面给出使用继承后的实现:
 class actor//基类{	protected:	int m_iHealth;	const int m_iSpeed;//为了方便,这个值使用延时值,越大表示速度越慢	const int m_iHitPoint;	char m_strName[260];	public:	actor(const char* strName,const int iHealth,const int iSpeed,const int iHitpoint);	int& Health(){ return m_iHealth; };	const char* getName(){ return m_strName; };	virtual void hit(actor *Actor) = 0;	bool isAlive(); }; actor::actor(const char* strName,const int iHealth,const int iSpeed,const int iHitpoint):m_iHealth(iHealth),m_iSpeed(iSpeed),m_iHitPoint(iHitpoint){	strcpy(m_strName,strName);}bool actor::isAlive(){	return (m_iHealth>0);}///////////////////////////////////////////////////////////类fighterclass fighter :public actor{	public:	fighter(const char* strName);	virtual void hit(actor *Actor);	private:};fighter::fighter(const char* strName):actor(strName,100,20,20){}void fighter::hit(actor *Actor){	Sleep(m_iSpeed);	if(!isAlive())	{	return ;	}	if(Actor&&Actor->isAlive())	{	//这里我们用一个函数做了左值,因为函数返回的是引用	if(isAlive())	Actor->Health() = Actor->Health() - m_iHitPoint;	}}///////////////////////////////////////////////////////////类knightclass knight :public actor{	public:	knight(const char* strName);	virtual void hit(actor *Actor);	private:};knight::knight(const char* strName):actor(strName,150,20,25){}void knight::hit(actor *Actor){	Sleep(m_iSpeed);	if(!isAlive())	{	return ;	}	if(Actor&&Actor->isAlive())	{	if(isAlive())	Actor->Health() = Actor->Health() - m_iHitPoint;	}}///////////////////////////////////////////////////////////类warriorclass warrio