理解继承、虚函数与多态

理解继承、虚函数与多态

示例代码(摘自《深入浅出MFC》)

第一节:

使用VS2005生成一个console程序,添加MyTestClass.h将如下代码添加到该头文件中
#include "string.h"
/*
    CEmployee是基类
    CWage、CManager为CEmployee的派生类
    CSales为CWage的派生类
*/

// Base Class 职员
class CEmployee
{
private:
 char m_Name[30];

public:
 CEmployee();
 CEmployee(const char *nm)
 {
  strcpy_s(m_Name,sizeof(m_Name),nm);
 }
 void getname()
 {
  printf("%s/n",m_Name);
 }
};

class CWage:public CEmployee
{
private:
 float m_wage;
 float m_hours;
public:
 CWage(const char *nm) : CEmployee(nm)
 {
  m_wage = 250.0;
  m_hours = 40.0;
 }
 float computePay()
 {
  return (m_wage * m_hours);
 }
};

class CSales:public CWage
{
private:
 float m_comm;
 float m_sale;
public:
 CSales(const char *nm):CWage(nm)
 {
  m_comm = m_sale = 0.0;
 }
 void SetCommission(float comm)
 {
  m_comm = comm;
 }
 float computePay()
 {
  return ( CWage::computePay() + m_comm * m_sale);
 }
};

class CManager:public CEmployee
{
private:
 float m_salary;
public:
 CManager(const char *nm):CEmployee(nm)
 {
  m_salary = 1500.0;
 }
 void setSalary(float salary)
 {
  m_salary = salary;
 }
 float computePay()
 {
  return m_salary;
 }
};

添加一个.cpp文件,并在cpp文件中添加如下代码:
#include "stdafx.h"
#include "MyTestClass.h"

int _tmain(int argc, _TCHAR* argv[])
{
 CManager aManager("管理");
 CSales   aSales("销售");
 CWage    aWager("其它");

 CEmployee *pEmployee[3];
 pEmployee[0] = &aManager;
 pEmployee[1] = &aSales;
 pEmployee[2] = &aWager;

 for (int i=0; i<3; i++)
  pEmployee[i]->getname();


 return 0;
}

输出结果会怎样呢?因为    CWage、CManager为CEmployee的派生类,CSales为CWage的派生类,所有的对象均从CEmployee派生出来,所以都会继承CEmplyee的成员,即所有的对象都有和getname函数。但是同一函数怎样处理不同的数据?为什么只调用了getname却可以处理不同的名称?实际上是this指针的功能,编译器在编译过后生成的代码中会添加一个隐匿的参数:this指针。在类的成员变量前面会加入this->来标志究竞是哪个对象正在处理。实际上当在处理CManager aManager("管理");时基类CEmployee中的m_Name成员变量前面加入了一个this指针,该指针就指向了对象aManager。所以程序输出结果为:
管理
销售
其它

现在我如果把CSales稍为改造一下,变成如下的样子,其它代码不作改动
class CSales:public CWage
{
private:
 float m_comm;
 float m_sale;

 char szName[30];
public:
 CSales(const char *nm):CWage(nm)
 {
  m_comm = m_sale = 0.0;
  strcpy(szName,nm);
 }
 void SetCommission(float comm)
 {
  m_comm = comm;
 }
 float computePay()
 {
  return ( CWage::computePay() + m_comm * m_sale);
 }
 void getname()
 {
  printf("销售类中的:%s/n",szName);
 }
};

我只是在CSales中加入了一个与基类相同的函数getname,那程序的输出结果会怎样呢?
程序将输出基类中的字符串呢?还是子类中的字符串呢?运行一下,输出结果如下
管理
销售
其它
为什么在第二行中不输出 “销售类中的:销售”这个字符串呢?哦,原因是:如果基类与派生类都定义了“相同名称这成员函数”,那么通过对象指针调用成员函数时,到底调用哪一个函数,必须视该指针的原始类型而定,而不是视指针实际所指的对象的类型而定。上面的例子中,指向对象的指针定义为CEmployee *pEmployee[3];那指针的原始类型为CEmployee,所以当然会执行CEmployee中的getname了。所以会有如上的输出结果。为了验证这个结论,我们再将.cpp文件修改一下,在for循环前面加入这么两行代码
 CSales *pSales = &aSales;
 pSales->getname();
或干脆点,变成这样的
 CSales *pSales;
 pEmployee[1] = pSales = &aSales;
 pSales->getname();
同样是把aSales对象的地址赋给两个指针,执行结果会一样吧?呵呵,运行一下:
销售类中的:销售
管理
销售
其它
结果如上,看样子是与该指针的原始类型决定了成员函数的调用。 

你可能感兴趣的:(理解继承、虚函数与多态)