现在我们来再来看看我们下面这个类,这是我们的电子表格的最终版本:
——————————————
#include “SpreadSheetData”
namespace My_Code{
class SpreadSheet
{
public:
SpreadSheet(int width,int high);
SpreadSheet(const SpreadSheet &
Data);
virtual ~SpreadSheet();
SpreadSheet&
operator=(const SpreadSheet &
Data);
void SetCellAt(int x,int y,const SpreadSheetCell&
Cell);
SpreadSheetCell&
GetCell(int x,int y);
protected:
SpreadSheetData *m_Data;
};
}
————————————–
大家也看到了,我们最终的Spreadsheet和SpreadsheetData有些像,其实不是有些像啦,他们的方法都是一样的,我们可以像使用SpreadSheetData一样使用他:
————————————-
f()
{
SpreadSheet myData(3,4);
myData.SetCellAt(2,2,6);
}
——————————————
像第四十一讲里面的一样,我们可以得到同样的结果。
那么现在大家是不是很好奇,为什么我们要把相同的两种方法实现两边呢?如果大家真有这种想法的话,我们可以来看下我们今天界面的实现方案:
——————————————
#include “Spreadsheet.h”
using namespace My_Code;
SpreadSheet::SpreadSheet(int width,int high)
{
m_Data = new SpreadSheetData(width,high);
}
SpreadSheet::~SpreadSheet()
{
m_Data->~SpreadSheetData();
}
SpreadSheet::SpreadSheet(const SpreadSheet&
Data)
{
m_Data = new SpreadSheetData(*(Data.m_Data));
}
SpreadSheet&
SpreadSheet::operator=(const SpreadSheet &
Data)
{
*m_Data = *Data.m_Data;
return *this;
}
void SpreadSheet::SetCellAt(int x,int y,const SpreadSheetCell &
cell)
{
m_Data->SetCellAt(x,y,cell);
}
SpreadSheetCell&
SpreadSheet::GetCell(int x,int y)
{
return m_Data->GetCell(x,y);
}
——————————————-
现在大家是不是有种如梦方醒的感觉呢?从表面上看上去,我们好像要将相同的方法实现两边,但实际上我们只是去调用我们已经准备好的方案,为什么要这样呢?因为这样更能体现出oo思想,将数据和方法彻底分离出来。
现在回来看看上面的实现,首先是构造函数,有些朋友可能想,为什么不直接去调用要重新new一个出来呢?哦,对了,既然大家发现了那我就只好告诉大家,因为对象是不能够调用就能够出来,那只是方法,要产生一个对象怎么办?必须得创建出来,创建一个对象我们需要相应的内存,而new不但可以动态分配内存,还能够创建出相应的对象,这就是为什么C++里面没人用malloc都用new的原因。
第二个大家可能觉得有些奇怪的地方:*m_Data = *Data.m_Data;
大家是不是想问,为什么不是m_Data = Data.m_Data呢?原因很简单,因为这样写的话其实只是将地址传递过去,也就是说,两个m_Data共同指向一块内存块,这样做极其危险,如果一旦某一边收回这块内存,那么另一边就指空,所以,我们要的不是复制地址,而是复制数据。
除了这两点可能让有部分朋友觉得疑惑之外想必没有啥问题了,那么现在我们重新回到昨天我们遗留下来的问题上来,关于这个辅助函数CopyFrom,难道大家都没有什么想法吗?是啊,不过只是个辅助函数而已,有没有其实没关系,不过就是多敲几句代码而已。
为什么我们引入这个辅助函数呢?大家应该注意到了,在第四十一讲的内容里面有几个函数使用到了相同的代码段,比如,赋值函数,复制构造函数:
————————————–
m_width = Data.m_width;
m_high = Data.m_high;
m_Cell = new SpreadSheetCell*[m_width];
for(int i=0;
i<m_width;
i++)
m_Cell[i] = new SpreadSheetCell[m_high];
for(int i=0;
i<m_width;
i++)
for(int j=0;
j<m_high;
i++)
m_Cell[i][j] = Data.m_Cell[i][j];
———————————————-
上面这段代码如果我们稍加留意的话会发现好几处都在使用,既然如此,我们何不使用一个辅助函数来实现呢?我们只需要调用这个函数就好,这样一来,整个代码块看上去就比较干净利落了。所以,这里就是我们CopyFrom的实现。
接下来,大家思考一个问题,如果我们要开发一个人事管理系统,我们该怎么着手?