友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

深入浅出MFC第2版(PDF格式)-第37章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




#0004  class CEmployee   // 职员 

#0005  { 

#0006  private: 

#0007  char m_name'30'; 

#0008 

#0009  public: 

#0010    CEmployee(); 

#0011    CEmployee(const char* nm) { strcpy(m_name; nm); } 

#0012  }; 



                                                                                    63 


…………………………………………………………Page 126……………………………………………………………

                  #0013  //……………………………………………………………………………………………………………………………………………………………………

                  #0014  class CWage : public CEmployee      // 时薪职员是一种职员 

                  #0015  { 

                  #0016  private : 

                  #0017    float m_wage; 

                  #0018    float m_hours; 

                  #0019 

                  #0020  public : 

                  #0021    CWage(const char* nm)  : CEmployee(nm) { m_wage = 250。0; m_hours = 40。0; } 

                  #0022    void setWage(float wg)  { m_wage = wg; } 

                  #0023    void setHours(float hrs)  { m_hours = hrs; } 

                  #0024    float putePay(); 

                  #0025  }; 

                  #0026  //……………………………………………………………………………………………………………………………………………………………………

                  #0027  class CSales : public CWage     // 销售员是一种时薪职员 

                  #0028  { 

                  #0029  private : 

                  #0030    float m_m; 

                  #0031    float m_sale; 

                  #0032 

                  #0033  public : 

                  #0034    CSales(const char* nm) : CWage(nm)  { m_m = m_sale = 0。0; } 

                  #0035    void setmission(float m)      { m_m = m; } 

                  #0036    void setSales(float sale)           { m_sale = sale; } 

                  #0037    float putePay(); 

                  #0038  }; 

                  #0039  //……………………………………………………………………………………………………………………………………………………………………

                  #0040  class CManager : public CEmployee   // 经理也是一种职员 

                  #0041  { 

                  #0042  private : 

                  #0043    float m_salary; 

                  #0044  public : 

                  #0045    CManager(const char* nm) : CEmployee(nm)  { m_salary = 15000。0; } 

                  #0046    void setSalary(float salary)              { m_salary = salary; } 

                  #0047    float putePay(); 

                  #0048  }; 

                  #0049  //……………………………………………………………………………………………………………………………………………………………………

                  #0050  void main () 

                  #0051  { 

                  #0052  CManager aManager(〃陈美静〃); 

                  #0053  CSales   aSales(〃侯俊杰〃); 

                  #0054  CWage    aWager(〃曾铭源〃); 

                  #0055  } 

                  #0056  //……………………………………………………………………………………………………………………………………………………………………

                  #0057  // 虽然各类別的 putePay 函数都没有定义,但因为程序也没有调用之,所以无妨。 



64 


…………………………………………………………Page 127……………………………………………………………

如此一来,CWage 继承了CEmpl oyee 所有的成员(包括资料与函数),CSales 又继承 



了CWage 所有的成员(包括资料与函数)。在意义上, 相当于CSales 拥有资料如下: 



    // private data of CEmployee 

   char m_name'30'; 



    // private data of CWage 

   float m_wage; 

   float m_hours; 



    // private data of CSales 

   float m_m; 

   float m_sale; 



 以及函数如下: 



   void setWage(float wg); 

   void setHours(float hrs); 

   void setmission(float m); 

   void setSale(float sales); 

   void putePay(); 



  从Visual C++  的除错器中,我们可以看到,上例的main 执行之后,程序拥有三个对象, 



  内容(我是指成员变量)分别为: 



                                                                                 65 


…………………………………………………………Page 128……………………………………………………………

从薪水说起 



    虚拟函数的故事要从薪水的计算说起。根据不同职员的计薪方式,我设计put ePay  函 



    数如下: 



       float CManager::putePay () 



        { 



            return m_salary; // 经理以「固定周薪」计薪。 



        } 



       float CWage::putePay () 



        { 



            return  (m_wage * m_hours); // 时薪职员以「钟点费* 每周工时」计薪。 



        } 



       float CSales::putePay () 



        { 



       // 销售员以「钟点费* 每周工时」再加上「佣金* 销售额」计薪。 



            return  (m_wage * m_hours + m_m * m_sale); // 语法错误。 



        } 



        CSales                  CWage   m_wage   m_hours           pr ivate 

    但是        对象不能够直接取用               的        和        ,因为它们是 



    成员变量。所以是不是应该改为这样: 



       float CSales::putePay () 



        { 



            return putePay () + m_m * m_sale; 



        } 



                                       put ePay       … 

    这也不好,我们应该指明函数中所调用的                            究归谁属  编译器没有厉害到能 



    够自行判断而保证不出错。正确写法应该是: 



       float CSales::putePay () 



        { 



            return CWage::putePay () + m_m * m_sale; 



        } 



    这就合乎逻辑了:销售员是一般职员的一种,他的薪水应该是以时薪职员的计薪方式作 



    为底薪,再加上额外的销售佣金。我们看看实际情况,如果有一个销售员: 



    CSales aSales(〃侯俊杰〃); 



                                                                                      66 


…………………………………………………………Page 129……………………………………………………………

那么侯俊杰的底薪应该是: 



   aSales。CWage::putePay (); // 这是销售员的底薪。注意语法。 



而侯俊杰的全薪应该是: 



   aSales。putePay (); // 这是销售员的全薪 



                                scope resolution operator :: 

结论是:要调用父类别的函数,你必须使用                               明白指出。 



接下来我要触及对象类型的转换,这关系到指针的运用,更直接关系到为什么需要虚拟 



函数。了解它,对于application framework 如MFC 者的运用十分十分重要。 



假设我们有两个对象: 



   CWage aWager; 



   CSales aSales(〃侯�
返回目录 上一页 下一页 回到顶部 赞(1) 踩(1)
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!