中的抽象物业
在C++中,以类、虚函数等为代表的数据抽象功能一直是C++的核心和难点。我认为C++的抽象应该是指:从我们需要解决的问题出发,在与该问题相关的一组关联对象中提取出主要的或共有的部分――说简单一点,就是用相同的行为来操作不同的对象。
从提出问题到找出与该问题相关的对象,这是一个互动的、反复的过程。在对相关对象的抽象中,随着认识的深入,我们可能会修改最初的目标,而最初目标的修改又可能使一组新的相关对象被加入进来。如:假设现在要设计一个基于广域的邮件服务器,首先可能需要通过socket对底层协议进行封装,为高层的pop3、smtp协议提供一组标准的接口。开始为了使问题简化我们可能计划只封装TCP/IP协议,不过基于以下两点我们有理由修改最初的需求:
1、pop3、smtp需要的底层接口很简单。除了连接,仅需要发送、接收一块数据的功能
2、用socket进行络编程,大多数常见协议间的差别很小,有许多都仅仅只是初始化和连接不同而已我们只需要做很小的努力就可以兼容大多数常用协议(如:ATM、Ipx、红外线协议等)。
现在决定修改需求,除了TCP/IP协议,还要支持一些其他的的常用协议。通过对最初目标的修改,除了TCP/IP协议对象,又会有一组相关的协议对象被加入进来。我们可以很容易从这组相关对象中提出共有的部分,将他抽象到另一个公共对象中。当然,根据具体应用环境不同,这可能并不是最佳方案。
C++中常规的抽象是在一组相互间有“血缘”关系的类中展开的。如:
Class Parent
{
virtual ~Parent(){};
virtual void GetValue(){ .... };
virtual void Test(){ ... };
};
class child1 :public parent
{
virtual ~child1(){};
virtual void GetValue(){...};
virtual void Test(){ ... } const;
};
class child2 :public parent
{
virtual ~child2(){};
virtual void GetValue(){...};
virtual void Test(){ ... } ;
};
(顺便说一句,child1::Test() const 不是基类 parent::Test() 的重载。)
由上可总结出C++中抽象的一些基本特点:
1、被抽象对象必须直接或间接派生至某个类对象
2、如果你不用没有类型安全的操作,如:向下转型操作或强制类型转化操作(像COM那样)。那么派生类中需要抽象的动作必须在某个基类中出现。
3、基类的析构函数必须是一个虚函数
上述特点一般而言不会影响我们的抽象,但在一些特殊情况下就很难说了。比如:
假设为某个项目进行二次开发,到手的资料可能就是一堆dll、一堆头文件和一堆文档。这些dll里输出了很多的类,其中有一大堆都是离散的、毫无关系的类对象。经过一段时间的开发,你可能发现为了分别操作这些对象,程序中充满了switch...case.../if....else....语句。更扰人的是其实这些对象完全可以从某个基类派生,有些操作完全可以定义成virtual function。但在不能修改source code 的情况下(其实就算有源代码这样的修改也不可行)如何对这组对象进行抽象呢?
还有一些例子,比如:在MFC中,假设我们从Cdialog派生一组对话框类,如果我们在某个派生类中定义了一个自己的virtual function。那么除了重新在Cdialog和派生类之间再派生一个类层次,我们无法从外部以抽象的方式直接调用这个虚函数。但为了一个派生类和一个virtual function就添加一个类层次,这也太.....
洗净切块;水发冬笋洗净切条;豌豆苗、金针菇、黄豆芽择洗干净 将以上特例总结一下:C++中进行抽象的一组类之间必须有“血缘”关系。但在实际应用中我们有
时候有必要对一组离散的、没有关系的类对象(如来自不同的类库或者根本就没有virtual function)进行一些抽象操作――可能因为工作关系,我接触这种情况的机会比较多。传统的C++没有直接提供这方面的支持。在实际应用中我经常使用如下方法:
#include list
class parent
{
public:
virtual ~parent(){};
virtual void DoSomething( void ) const = 0;
};
template typename T
class child : public parent
{
public:
virtual ~child()
{
delete tu;
}
child( ):
{
tu = new T;
}
void DoSomething( void ) const
{
tu-InitObj();
}
private:
T *tu;
};
class test
{
public:
void InitObj( void )
{
::MessageBox( NULL, \"Test\", \"test...ok!\", MB_OK );
}
};
int main()
{
using namespace std;
list parent* plist;
parent *par = new childtest();
sh_back( par );
}
石家庄白癜风医院排名广州治疗盆腔炎哪家好
乌鲁木齐白癜风哪好
- 上一页:中的引用
- 下一页:中的数组和中数组的区别计划
-
清华大学!郓城1名许多学生通过
近日 初等教育部天空高考信息公开平台 公布了 2022年的学校专项开发计划 主...
2024-12-26
-
为了封控期间的团购,“团团长”、业主和志愿者吵起来了!还闹上了法庭
新民晚报传讯(美联社 杨程 美联社 孙云)因为非典型肺炎封控之前电子商务...
2024-12-26
-
美股短线跳水 三大股指剩余转跌
美股短线蹦床 三大期权才将转滑落 【美股短线蹦床 三大期权才将转滑落】...
2024-12-26
-
索尼爱立信 G11 通过 FCC 认证,配备 5000 万像素后置摄像头
IT之家 5 月 22 日消息,去年 2 月,爆料者 @Roland Quandt 放出了索尼爱立信 G11 和...
2024-12-26
-
少女时代崔秀英,奢华肩线,笔直锁骨,时尚又不失可爱的酒店拍摄
精彩内容回顾 1、 2022年韩张怡宁东亚点击量前十名,动态选举专贴! 2、 20...
2024-12-26
-
2022年北京中考成绩公布,下周一起填报志愿者
2022年年级升学水平笔试佳绩键入系统对昨天开通,各区最高分段数目统计学...
2024-12-26