Employee与Manager就是基类与继承类的关系:
当我们令 Manager 继承 Employee 时,目的除了是要表示它们之间的相似关系以外,还要让 Manager 的操作集利用继承关系的描述而自然地发生扩张。对 Employee 数据结构的继承只是手段而不是目的。
下面,用一个例子来帮助我们理解继承机制:
某公司有普通职员和管理者两种员工,每位职员都有姓名、年龄、工龄和所在部门号等属性,管理者除了具有这些属性之外,还有级别属性(通常在公司的管理层中有一级经理、二级经理等)和一个数组(存储他直接管理的所有员工信息)。请定义和实现两个类:Employee(普通员工)、Manager(管理者),并使它们的对象满足以下给定程序。
int main()
{
Employee e("Jack", 24, 2, "Development");
Manager m("Tom", 30, 5, "Development", 2);
m.addMember(&m).addMember(&e);
e.printOn(); // 显示Jack的所有信息
m.printOn(); // 显示Tom的所有信息
Employee* p = &e;
bool b = p->retire(); // 若p所指对象的年龄大于55岁,则b为true
p = &m;
b = p->retire (); // 若p所指对象的年龄大于60岁,则b为true
// 将显示: Total 2 employee’s object created.
cout << "Total " << Manager::count()
<< " employee's object created.";
}
1.根据题意所述,可以分别得出Employee和Manager的成员变量和成员函数
这里应注意的是派生类的构造函数的编写,初始化顺序遵循:基类,成员,派生类自己,格式如下:
Manager(string s1, int n, int y, string s2, int z) : Employee(s1, n, y, s2)
{ level = z; current = 0; )Manager(string s1, int n, int y, string s2, int z) : Employee(s1, n, y, s2) , level(z),
{ current = 0; )
其次还要注意到retire这个函数,雇员的退休年龄是55,经理退休年龄是60,可见这是c++中典型的动态多态——虚拟函数,因此retire应被编写为虚拟函数。
printOn函数可以编写为虚拟函数,也可以编写为各自的成员函数。
count函数应为Manager类的静态成员函数,返回静态成员变量(静态成员变量应置于基类中),用于统计被创建对象的个数。
静态变量的初始化应该在类外进行,此外还应主要,静态成员变量只能由静态成员函数去调用。
虚拟函数retire的编写如下:
在Employee类中:
enum {EMPLOYEE_RETIRE = 55};
virtual bool retire()
{ return age > EMPLOYEE_RETIRE ? true : false; }
在Manager类中:
enum {MANAGER_RETIRE = 60};
virtual bool retire()
{ return age > MANAGER_RETIRE ? true : false; }调用方式:这里选择指针调用(虚拟函数的两种调用方式请移步另一篇博客)
Employee* p = &e;
bool b = p->retire(); // 若p所指对象的年龄大于55岁,则b为true
p = &m;
b = p->retire (); // 若p所指对象的年龄大于60岁,则b为true
printOn函数的编写,这里将其视为普通的成员函数:
Employee类中:
void printOn() {
cout << "Name: " << name << '\t' << "Age: " << age << '\t'
<< "WorkYear: " << workYears << '\t'
<< "Department: " << dept << endl;
}Manager类中:
void printOn(){
Employee::printOn();
cout << "Level: " << level << endl;
}
静态成员函数count的编写:
Manager类中:
static int count() { return Employee::counts; } //这里返回基类中的静态变量counts,用于记录被创建对象的个数
Employee类中:
Employee(string s1, int n, int y, string s2) {
name = s1; age = n; workYears = y; dept = s2;
counts++;//派生类对象的创建也会调用基类的构造函数,故counts是记录所有被创建对象的个数
}静态变量counts的初始化:
在Employee类外进行:int Employee::counts = 0;
另外,不论是静态成员变量还是静态成员函数,都是以类为作用域的(而非以对象为作用域)
因为静态成员是所有对象共用的一块公共内存区域。因此,他们的调用是下面这样的:
Manager::count()和Employee::counts;
addMember函数的编写:
Manager类中:
Manager addMember(Employee* em) {
emps[current++] = *em; //emps数组存储当前经理所管理的员工,current从零开始
return *this;
}
2.完整程序
#include<iostream>
#include<string>
using namespace std;
class Employee {
protected:
string name;
int age;
int workYears;
string dept;
static int counts; // 统计创建的对象个数
public:
enum {EMPLOYEE_RETIRE = 55};
Employee() { }
Employee(string s1, int n, int y, string s2) {
name = s1; age = n; workYears = y; dept = s2;
counts++;
}
void printOn() {
cout << "Name: " << name << '\t' << "Age: " << age << '\t'
<< "WorkYear: " << workYears << '\t'
<< "Department: " << dept << endl;
}
virtual bool retire() {
return age > EMPLOYEE_RETIRE ? true : false;
}
};
int Employee::counts = 0;
class Manager : public Employee {
public:
enum {MAX_NUMBERS = 5, MANAGER_RETIRE = 60};
Manager(string s1, int n, int y, string s2, int z) : Employee(s1, n, y, s2)
{ level = z; current = 0; }
void printOn(){
Employee::printOn();
cout << "Level: " << level << endl;
}
virtual bool retire()
{ return age > MANAGER_RETIRE ? true : false; }
Manager addMember(Employee* em) {
emps[current++] = *em;
return *this;
}
static int count() { return Employee::counts; }
private:
int level;
Employee emps[MAX_NUMBERS];
int current;
};
int main()
{
Employee e("Jack", 24, 2, "Development");
Manager m("Tom", 30, 5, "Development", 2);
m.addMember(&m).addMember(&e);
e.printOn(); // 显示Jack的所有信息
m.printOn(); // 显示Tom的所有信息
Employee* p = &e;
bool b = p->retire(); // 若p所指对象的年龄大于55岁,则b为true
p = &m;
b = p->retire (); // 若p所指对象的年龄大于60岁,则b为true
// 将显示: Total 2 employee’s object created.
cout << "Total " << Manager::count()
<< " employee's object created.";
}
3.运行截图