📄 chapter8.htm
字号:
<br>
Point() { _x = _y = 0; }<br>
<br>
int x() { return _x; }<br>
int y() { return _y; }<br>
private:<br>
int _x, _y;<br>
};</p>
<p class=style3>Point& Point::operator++()<br>
{<br>
_x++;<br>
_y++;<br>
return *this;<br>
}</p>
<p class=style3>Point Point::operator++(int)<br>
{<br>
Point temp = *this;<br>
++*this;<br>
return temp;<br>
}</p>
<p class=style3>Point& Point::operator--()<br>
{<br>
_x--;<br>
_y--;<br>
return *this;<br>
}</p>
<p class=style3>Point Point::operator--(int)<br>
{<br>
Point temp = *this;<br>
--*this;<br>
return temp;<br>
}</p>
<p class=style3>void main()<br>
{<br>
Point A;<br>
cout << "A的值为:" << A.x() << " , " << A.y() << endl;<br>
A++;<br>
cout << "A的值为:" << A.x() << " , " << A.y() << endl;<br>
++A;<br>
cout << "A的值为:" << A.x() << " , " << A.y() << endl;<br>
A--;<br>
cout << "A的值为:" << A.x() << " , " << A.y() << endl;<br>
--A;<br>
cout << "A的值为:" << A.x() << " , " << A.y() << endl;<br>
}</p>
<p class=style3>程序运行输出:<br>
A的值为:0 , 0<br>
A的值为:1 , 1<br>
A的值为:2 , 2<br>
A的值为:1 , 1<br>
A的值为:0 , 0<br>
</p>
<p class=style2>8-11 定义一个基类BaseClass,从它派生出类DerivedClass,BaseClass有成员函数fn1()、fn2(),fn1()是虚函数,DerivedClass也有成员函数fn1()、fn2(),在主程序中定义一个DerivedClass的对象,分别用BaseClass和DerivedClass的指针来调用fn1()、fn2(),观察运行结果。</strong><br>
</p>
<p class=style3>解: <br>
#include <iostream.h></p>
<p class=style3>class BaseClass<br>
{<br>
public:<br>
virtual void fn1();<br>
void fn2();<br>
};<br>
void BaseClass::fn1()<br>
{<br>
cout << "调用基类的虚函数fn1()" << endl;<br>
}<br>
void BaseClass::fn2()<br>
{<br>
cout << "调用基类的非虚函数fn2()" << endl;<br>
}</p>
<p class=style3><br>
class DerivedClass : public BaseClass<br>
{<br>
public:<br>
void fn1();<br>
void fn2();<br>
};<br>
void DerivedClass::fn1()<br>
{<br>
cout << "调用派生类的函数fn1()" << endl;<br>
}</p>
<p class=style3>void DerivedClass::fn2()<br>
{<br>
cout << "调用派生类的函数fn2()" << endl;<br>
}</p>
<p class=style3>void main()<br>
{<br>
DerivedClass aDerivedClass;<br>
DerivedClass *pDerivedClass = &aDerivedClass;<br>
BaseClass *pBaseClass = &aDerivedClass;<br>
<br>
pBaseClass->fn1();<br>
pBaseClass->fn2();<br>
pDerivedClass->fn1();<br>
pDerivedClass->fn2();<br>
}</p>
<p class=style3>程序运行输出:<br>
调用派生类的函数fn1()<br>
调用基类的非虚函数fn2()<br>
调用派生类的函数fn1()<br>
调用派生类的函数fn2()</p>
<p class=style3> </p>
<p class=style2>8-12 定义一个基类BaseClass,从它派生出类DerivedClass,BaseClass中定义虚析构函数,在主程序中将一个DerivedClass的对象地址赋给一个BaseClass的指针,观察运行过程。</strong><br>
</p>
<p class=style3>解: <br>
#include <iostream.h></p>
<p class=style3>class BaseClass {<br>
public:<br>
virtual ~BaseClass() {<br>
cout << "~BaseClass()" << endl;<br>
}<br>
};</p>
<p class=style3>class DerivedClass : public BaseClass {<br>
public:<br>
~DerivedClass() {<br>
cout << "~DerivedClass()" << endl;<br>
}<br>
};</p>
<p class=style3>void main()<br>
{<br>
BaseClass* bp = new DerivedClass;<br>
delete bp; <br>
} </p>
<p class=style3>程序运行输出:<br>
~DerivedClass()<br>
~BaseClass()<br>
</p>
<p class=style2>8-13 定义Point类,有成员变量X、Y,为其定义友元函数实现重载+。</strong><br>
</p>
<p class=style3>解: <br>
#include <iostream.h></p>
<p class=style3>class Point<br>
{<br>
public:<br>
Point() { X = Y = 0; }<br>
Point( unsigned x, unsigned y ) { X = x; Y = y; }<br>
<br>
unsigned x() { return X; }<br>
unsigned y() { return Y; }<br>
void Print() { cout << "Point(" << X << ", " << Y << ")" << endl; }<br>
<br>
friend Point operator+( Point& pt, int nOffset );<br>
friend Point operator+( int nOffset, Point& pt );<br>
<br>
private:<br>
unsigned X;<br>
unsigned Y;<br>
};</p>
<p class=style3>Point operator+( Point& pt, int nOffset )<br>
{<br>
Point ptTemp = pt;<br>
ptTemp.X += nOffset;<br>
ptTemp.Y += nOffset;<br>
<br>
return ptTemp;<br>
}</p>
<p class=style3>Point operator+( int nOffset, Point& pt )<br>
{<br>
Point ptTemp = pt;<br>
ptTemp.X += nOffset;<br>
ptTemp.Y += nOffset;<br>
<br>
return ptTemp;<br>
}</p>
<p class=style3>void main()<br>
{<br>
Point pt( 10, 10 );<br>
pt.Print();<br>
<br>
pt = pt + 5; // Point + int<br>
pt.Print();<br>
<br>
pt = 10 + pt; // int + Point<br>
pt.Print();<br>
}</p>
<p class=style3>程序运行输出:<br>
Point(10, 10)<br>
Point(15, 15)<br>
Point(25, 25)</p>
<p></p>
<p></p>
<p class=style3><br>
<strong>8-14 为某公司设计一个人事管理系统,其基本功能为输入、编辑、查看和保存公司的人事档案。职工人事档案包括姓名、性别、出生日期、婚姻状况、所在部门、职务和工资。</strong><br>
</p>
<p class=style3>程 序:</p>
<p class=style3>由于列表框尚未初始化,所以为CEmpDlg类重载OnInitDialog()成员函数(可使用ClassWizard完成),并添加相应代码:<br>
BOOL CEmpDlg::OnInitDialog() <br>
{<br>
CListBox *pLB = (CListBox *)GetDlgItem(IDC_DEPT);<br>
pLB->InsertString(-1, "办公室");<br>
pLB->InsertString(-1, "开发部");<br>
pLB->InsertString(-1, "生产部");<br>
pLB->InsertString(-1, "销售部");<br>
pLB->InsertString(-1, "人事部");<br>
return CDialog::OnInitDialog();<br>
}<br>
其中GetDlgItem()为对话框类的成员函数,用于取对话框控件的指针。<br>
为项目添加有关自定义的职工类CEmployee。选择Developer Studio菜单的Insert/New Class…选项,调出New Class对话框。在Class Type组合框中选择Generic(普通类),填写类名CEmployee,在对话框下方的Base class (es)框中输入基类CObject。<br>
在Workspace窗口的Class View中选择生成的CEmployee类的定义,添加代码:<br>
class CEmployee : public CObject <br>
{<br>
DECLARE_SERIAL(CEmployee)<br>
public:<br>
CString m_strName; // 姓名<br>
int m_nSex; // 性别<br>
COleDateTime m_tBirthdate; // 出生日期<br>
BOOL m_bMarried; // 婚否<br>
CString m_strDept; // 工作部门<br>
CString m_strPosition; // 职务<br>
float m_fSalary; // 工资<br>
CEmployee(){}<br>
CEmployee& operator = (CEmployee& e);<br>
virtual ~CEmployee();<br>
virtual void Serialize(CArchive &ar);<br>
};<br>
CEmployee类的对象即为一个职工的档案,我们用序列化实现文档的存取,所以要为CEmployee类编写序列化代码。这包括DECLARE_SERIAL()宏和IMPLEMENT_SERIAL()宏(在CEmployee类的源代码文件中),一个没有参数的构造函数,重载的赋值运算符和Serialize()成员函数。在CEmployee类的源代码文件中添加以下代码:<br>
IMPLEMENT_SERIAL(CEmployee, CObject, 1)<br>
// 重载的赋值运算符<br>
CEmployee& CEmployee::operator = (CEmployee& e)<br>
{<br>
m_strName = e.m_strName;<br>
m_nSex = e.m_nSex;<br>
m_tBirthdate = e.m_tBirthdate;<br>
m_bMarried = e.m_bMarried;<br>
m_strDept = e.m_strDept;<br>
m_strPosition = e.m_strPosition;<br>
m_fSalary = e.m_fSalary;<br>
return *this;<br>
}<br>
// 序列化函数<br>
void CEmployee::Serialize(CArchive& ar)<br>
{<br>
CObject::Serialize(ar);<br>
if(ar.IsStoring())<br>
{<br>
ar << m_strName;<br>
ar << m_nSex;<br>
ar << m_tBirthdate;<br>
ar << m_bMarried;<br>
ar << m_strDept;<br>
ar << m_strPosition;<br>
ar << m_fSalary;<br>
}<br>
else<br>
{<br>
ar >> m_strName;<br>
ar >> m_nSex;<br>
ar >> m_tBirthdate;<br>
ar >> m_bMarried;<br>
ar >> m_strDept;<br>
ar >> m_strPosition;<br>
ar >> m_fSalary;<br>
}<br>
}<br>
然后修改文档类CMyDocument类定义,添加一个CEmployee类的数组:<br>
#include "employee.h"<br>
#define MAX_EMPLOYEE 1000<br>
class CMy1501Doc : public CDocument<br>
{<br>
DECLARE_DYNCREATE(CMy1501Doc)<br>
public:<br>
CEmployee m_empList[MAX_EMPLOYEE];<br>
int m_nCount;<br>
public:<br>
virtual BOOL OnNewDocument();<br>
virtual void Serialize(CArchive& ar);<br>
virtual void DeleteContents();<br>
DECLARE_MESSAGE_MAP()<br>
};<br>
为了节省篇幅,这段程序经过删节,与原来由AppWizard生成的程序有所不同。其中黑体部分为要添加的代码。注意重载成员函数DeleteContents()可以手工进行,也可以通过ClassWizard进行。Serialize()和DeleteContents()两个成员函数的代码如下:<br>
void CMy1501Doc::Serialize(CArchive& ar)<br>
{<br>
if(ar.IsStoring())<br>
ar << m_nCount;<br>
else<br>
ar >> m_nCount;<br>
for(int i=0; i<m_nCount; i++)<br>
m_empList[i].Serialize(ar);<br>
}<br>
void CMy1501Doc::DeleteContents() <br>
{<br>
m_nCount = 0; // 在打开文件和建立新文件时将数组大小置0<br>
CDocument::DeleteContents();<br>
}<br>
即在文档类的Serialize()函数中,数据的序列化工作是通过调用Cemployee类的Serialize()函数实现的。<br>
实际上,要为本程序添加的大部分代码均在视图类中。首先在视图类CmyView类的定义中添加一个用于记录当前操作的是哪个记录的数据成员:<br>
int m_nCurrEmp;<br>
并为视图类重载OnInitialUpdate()成员函数,在其中初始化该变量:<br>
void CMy1501View::OnInitialUpdate() <br>
{<br>
CView::OnInitialUpdate();<br>
m_nCurrEmp = 0;<br>
Invalidate();<br>
}<br>
视图类的OnDraw()成员函数用于显示正在操作的职工档案:<br>
void CMy1501View::OnDraw(CDC* pDC)<br>
{<br>
CMy1501Doc* pDoc = GetDocument();<br>
ASSERT_VALID(pDoc);<br>
// 显示职工人数和当前职工编号<br>
CString s;<br>
s.Format("职工人数: %d", pDoc->m_nCount);<br>
pDC->SetTextColor(RGB(255, 0, 0));<br>
pDC->TextOut( 40, 40, s);<br>
s.Format("职工编号: %d", m_nCurrEmp+1);<br>
pDC->TextOut(340, 40, s);<br>
pDC->MoveTo( 40, 70);<br>
pDC->LineTo(600, 70);<br>
// 如果档案非空, 显示当前记录<br>
if(pDoc->m_nCount > 0)<br>
{<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -