c++学习笔记十四

 继承


  1 类和面向对象编程
  2 类的继承
       继承和聚合
       从基类中派生新类   头文件 Box.h示例代码如下:
       #ifndef BOX_H
       #define BOX_H 
       
       class Box{
        //构造器
        public:
 Box(double lv=1.0,double wv=1.0,double hv=1.0);


        private:
          double length;
          double width;
          double height;
       };
       #endif
       实现文件Box.cpp如下:
       #include "box.h"
       
       Box::Box(double lv,double wv,double hv):length(lv),width(wv),height


(hv){}
 
       定义一个carton是Box的派生类,Carton.h头文件的示例代码如下:
        #ifndef CARTON_H
        #define CARTON_H
        #include "Box.h"
 
        class Carton: public Box{  //public是基类访问指定符
          
          public:
             Carton(const char* pStr="Cardboard");//构造器
            ~Carton();//析构函数
     
          //成员变量
          private:
             char * pMaterial;//合成材料
        };
        #endif
       
         实现文件Carton.cpp,示例代码如下:
         #include "Carton.h"
         #include <cstring>
 
         //构造函数
         Carton::Carton(const char* pStr){
             pMaterial=new char[strlen(pStr)+1]; //分配空间
             std::strcpy(pMaterial,pStr);    //复制内容 
         }
         
         //析构函数
         Carton::~Carton(){
           delete[] pMaterial;
         }
        
         使用派生类
        #include <iostream>
        #include "Box.h"
        #include "Carton.h"
        using std::cout;
        using std::endl;


        int main(){
           Box myBox(40.0,30.0,20.0);
           Carton myCarton;
           Carton candyCarton("Thin cardboard");


           cout<<endl
               <<"myBox occupies"<<sizeof myBox<<"bytes"<<endl;
           cout<<"myCarton occupies"<<sizeof myCarton<<"bytes"<<endl;
           cout<<"candyCarton occupies"<<sizeof candyCarton<<"bytes"<<endl;
           
 //以下两句在编译时会发生错误,因为length是Box的私有成员
 // myBox.length=10.0;  
           //candyCarton.length=10.0;


           return 0;
        }
        注: 其中每个数据成员占8个字节


       
     3 继承下的访问控制
         Carton.h头文件的示例代码如下 :
        #ifndef CARTON_H
        #define CARTON_H
        #include "Box.h"
 
        class Carton: public Box{  //public是基类访问指定符
          
          public:
             Carton(const char* pStr="Cardboard");//构造器
            ~Carton();//析构函数


 //成员方法
           double volume() const;
     
          //成员变量
          private:
             char * pMaterial;//合成材料
        };
        #endif


         实现文件Carton.cpp,示例代码如下:
         #include "Carton.h"
         #include <cstring>
 
         //构造函数
         Carton::Carton(const char* pStr){
             pMaterial=new char[strlen(pStr)+1]; //分配空间
             std::strcpy(pMaterial,pStr);    //复制内容 
         }
         
         //析构函数
         Carton::~Carton(){
           delete[] pMaterial;
         }
 
         //成员方法
         double Carton::volume() const{
            return length*width*height;
         }




        基类成员函数
        
        基类头文件 Box.h
        class Box{
           public:
               Box(double lv=1.0,double wv=1.0,double hv=1.0);
           double volume() const;
        
           private:
               double length;
               double width;
               double height;
        };
        实现文件Box.cpp
          #include "Box.h"
         
          //构造函数
          Box::Box(double lv,double wv,double hv):length(lv),width


(wv),height(hv){}
          double Box::volume() const{
             return length*width*height;
          }
  
          在派生类中使用基类函数
          #include <iostream>
          #include "Box.h"
          #include "Carton.h"
          using std::cout;
          using std::endl;


          int main(){
    //实例化对象
            Box myBox(40.0,30.0,20.0);
           Carton myCarton;
           Carton candyCarton("Thin cardboard");
        
           cout<<endl
               <<"myBox volume is"<<myBox.volume()<<endl;
           cout<<"myCarton volume is"<<myCarton.volume<<endl;
           cout<<"candyCarton volume 


is"<<candyCarton.volume<<"bytes"<<endl;


          } 


      4 把类的成员声明为protected 
          这样派生类可以访问其成员


      5 派生成员的访问级别 public protected和private (默认) 共有9种不同的组



       访问级别如下图所示


         ============                         ===============
          公共的基类 ------------------------>   派生类
         ============                         ===============
           公共成员  ------------------------>     公共
         ============                         ===============
         受保护的成员------------------------>   受保护的
         ============                         ===============
           私有成员  ------------------------> 继承但不能访问
         ============                         ===============






============                         ===============
         受保护的基类 ----------------------->   派生类
         ============                         ===============
           公共成员  ------------------------>  受保护的
         ============                         ===============
         受保护的成员------------------------>  受保护的
         ============                         ===============
           私有成员  ------------------------> 继承但不能访问
         ============                         ===============








============                         ===============
         私有的基类 ------------------------>   派生类
         ============                         ===============
           公共成员  ------------------------>   私有
         ============                         ===============
         受保护的成员------------------------>   私有
         ============                         ===============
           私有成员  ------------------------> 继承但不能访问
         ============                         ===============


          在类层次中使用访问指定符
          改变继承成员的访问指定符 示例代码如下:
        Box.h头文件
class Box{
           public:
               Box(double lv=1.0,double wv=1.0,double hv=1.0);
           double volume() const;
        
           private:
               double length;
               double width;
               double height;
        };


        Box.cpp实现文件            
          #include "Box.h"
         
          //构造函数
          Box::Box(double lv,double wv,double hv):length(lv),width


(wv),height(hv){}
          double Box::volume() const{
             return length*width*height;
          }
 
         使用以下方法将派生类中的函数改为公共成员
          class Package: private Box{
             public:
                using Box::volume;
    };
        
       6  派生类中的构造函数操作
          调用基类的构造函数
          
          class Carton:public Box{
              //调用基类默认构造函数
              Carton(const char * pStr ="Cardboard");
              Carton(double lv,double wv,double hv,const char * 


pStr="Cardboard");
 
              //析构函数
              ~Carton();
 
              //成员方法
              double volume() const;
 
              protected: 
                  char * pMaterial;
          } 
        
           实现文件Carton.cpp
           #include "Carton.h"
           #include <cstring>
           #include <iostream>  
           
            using std::cout;
            using std::endl;
            //构造器
            Carton::Carton(const char * pStr){
                pMaterial=new char[strlen(pStr)+1];//分配空间
                std::strcpy(pmaterial,pStr);
                cout<<"Carton constructor 1"<<endl;
            }
          
            Carton::Carton(double lv,double wv,double hv,const char * 


pStr):Box(lv,wv,hv){
                  pMaterial=new char[strlen(pStr)+1];
                  std::strcpy(pMaterlal,pStr);
                  cout<<"Carton constructor 2"<<endl;
            }
 
            Carton::~Carton(){
               delete[] pMaterial;
            }


            double Carton::volume() const{
               return length*width*height;
            }


           在程序实例化的时候,编译器会首先调用Box的构造器


           派生类中的副本构造函数
            Box myBox(2.0,3.0,4.0);
            Box copyBox(myBox);
            需要在基类中添加一个副本构造函数(副本构造参数指定为引用) Box.h 


中添加如下代码
             Box::Box(const Box & aBox):length(aBox.length),width


(aBox.width),height(aBox.height){
                 cout<<""<<endl;
             }
            在Carton.h中添加
             Carton(const Carton & aCarton);//副本构造函数

            派生类中也要添加自已的构造函数,在Carton.cpp中添加如下:
            Carton::Carton(const Carton & aCarton):Box(aCarton){
                pMaterial=new char[strlen(aCarton.pMaterisl)+1];//分配空间
                strcpy(pMaterial,aCarton.pMaterial) ;              


                cout<<"Carton copy constructor"<<endl;
            }
         
        7 继承中的析构函数 (在派生类对象超出作用域,或位于自由存储区时,必


须要释放他)    先调用派生类中的析构函数,后调用基类中的析构函数
        8 重复的成员名
          示例代码如下:
           class Base{
               //构造函数
               public:
                  Base(int number=10){value=number;}
               
               //数据成员
               protected:
                  int value;
           } 
           派生类Derived
           class Derived:public Base{ 
              public:
                 Derived(int number=20){value=number;}
                 int total() const;
           
              protected:
                 int value; //定义了重复成员名
           } 
          使用时必需指定其作用域(使用基类名和作用域解析运算符) 示例代码如下


:
            int Derived::total() const{
                return value+Base::value;
            }


          重复的函数成员名
            第一种情况:函数名相同,但参数列表不同
              class Base{
                public:
                   void doThat(int arg);
           ...
               };
              
               class Derived::public Base{
                   public:
                      void doThat(double arg);
                      using Base::doThat();
                          ...
                };
            第二种情况:所有方面都相同
              Derived object;
              object.Base::doThat(3);//调用基类的函数
       
          9 多重继承
             派生类可以有任意多个直接基类(这个跟java有点不同)
             多个基类,示例代码如下:
               class CerealPack:public Carton,public Contents{
                   ...
               }
             继承成员的模糊性
          
       头文件的定义如下========================================
               #ifndef BOX_H
               #define BOX_H 
       
               class Box{
                 
                   public:
             Box(double lv=1.0,double wv=1.0,double hv=1.0); //构


造器
                      Box(const Box & aBox);//副本构造器
                       
                       //析构函数
                       ~Box();
 
                   private:
                      double length;
                      double width;
                      double height;
               };
               #endif
               ==========================================================
               实现文件
               #include "Box.h"
               #include <iostream>
               using std::cout;
               using std::endl;
                
      //默认构造器
               Box::Box(double lv,double wv,double hv):length(lv),width


(wv),height(hv){
                 cout<<"Box constructor"<<endl;
               } 
   
               //副本构造成器
               Box::Box(const Box & aBox):length(lv),width(wv),height(hv){
                  cout<<"Box copy constructor called"<<endl;
               }
 
               //析构函数
               Box::~Box(){
                 cout<<"Box destructor"<<endl;
               }
               
               //成员方法
               double Box::volume() const{
                   return length*width*height;
               }
               ===========================================================
               以下是派生类 
                头文件Carton.h
                #ifndef CARTON_H
                #define CARTON_H
                #include "Box.h"
       
                class Carton: public Box{
                    //构造器
                    pulbic : 
                       Carton(double lv=1.0,double wv=1.0,double 


hv=1.0,const char * pStr="Cardboard",double dense=0.125,double thick=0.2);
 
                    //析构函数
                    ~Carton(); 
                
                    double getWeight() const;
                    
                    //成员变量
                    char * pMaterial;
                    double thickness; //厚度
                    double density; //密度
                };
                #endif
               ==========================================================
                实现文件Carton.cpp
                #include "Carton.h"
                #include <cstring>
                #include <iostream>
                using std::cout;
                using std::endl;


                //构造器
               Carton:: Carton(double lv,double wv,double hv,const char * 


pStr,double dense,double thick):Box(lv,wv,hv),density(dense),thisckness


(thick){
               pMaterial =new char[strlen(pStr)+1];//分配空间
               strcpy(pMaterial,pStr);
               cout<<"Carton constructor"<<endl;          
               }
               
               //析构函数
               Carton::~Carton(){
                   cout<<"Carton destructor"<<endl;
    delete[] pMaterial;
               }


               //取得重量
 
               double Carton::getWeight() const{
                    return 2*(length*width+width*height+height*length)


*thickness*density;
               }
               ============================================================
              Contents.h头文件
              #ifndef CONTNETS_H
              #define CONTENTS_H
  
              class Contents{
                  //构造器
                  public:
                     Contents(const char * pStr="cereal",double 


weight=0.3,double vol=0);
                     
                  //析构函数
                  ~Contents();
                  double getWeight() const;//取得重量
                  
                  //成员变量
                    char* pName;
                    double volume;
                    double unItweight;       
              };
              #endif
            ==============================================================
            Contents.cpp实现文件
             #include "Contents.h"
             #inlcude <cstring>
             #include <iostream>
             using std::cout;
             using std::endl;  


             //构造器
             Contents::Contents(const char* pStr,double weight,double 


vol):unitweight(weight),volume(vol){
             pName=new char[strlen(pStr)+1];
             std:strcpy(pName,pStr);
             cout<<"Contents constructor"<<endl;        
             }
             
             //析构函数
             Contents::~Contents(){
                   delete[] pName;
                   cout<<"Contents destructor"<<endl;
             }


             //取得重量
             double Contents::getWeight() const{
                return volume*unitweight;
             }
             ============================================================
             现在把Carton和Contents类作为公共基类
              CerealPack.h 头文件 
              #ifndef CERALPACK_H
              #define CERALPACK_H
              #include "Carton.h"
              #include "Contents.h"
              //CerealPack是carton和contents 的派生类
              class CerealPack:public Carton,public Contents{
                  //构造器
                  public:
                     CerealPack(double length,double width,double 


height,const char * cerealType);
                  
                  //析构函数
                  ~CerealPack();
              };
              #endif
             ==============================================================
              CerealPack.cpp实现文件如下
              #include <iostream>
              #include "Carton.h"
              #include "Contents.h"
              #include "Cerealpack.h"
               
              using std::cout;
              using std::endl;
              CerealPack::CerealPack(double length,double width,double 


height,const char * cerealType):Carton


(length,width,height,"cadboard"),Contents(cerealType){
                 cout<<"CerealPack constructor"<<endl;
                 Contents::volume=0.9*Carton::volume();
              }
             =============================================================
             使用多重继承 示例代码如下:
             #include <iostream>
             #include "CerealPack.h"
             using std::endl;
             using std::cout;
       
              int main(){
                 CerealPack packofFlakes(8.0,3.0,10.0,"Cornflakes");
         
                 
                 cout<<endl
                     <<"packofFlakes volume is"
                     <<packofFlakes.Carton::volume()
                     <<endl;
       
                 cout<<endl 
                     <<"packofFlakes weight is"
                     


<<packofFlakes.Crton::getWeight+packofFlakes.Contents::getWeight()
                     <<endl; 
                 return 0;
              }
             
             重复的继承


             虚基类 示例代码如下:(基类应只出现一次)
             class Contents:public virtual Comon{
                    ...
             };
             
             class Box:public virtual Common{
                    ...
             };
           
             ==========================================================
             class Freebie:public Common{ 
                  ...
              };
             
             class cerealPack:pulbic Carton,public Contents,publicFreebie{
                  ...
             };
             如果Common也声明为Freebie的虚基类,CerealPack类就只能继承


Common类型的一个子对象
            
            10 在相关的类类型之间的转换
              把派生类转换为基类类型,示例代码如下:
              Carton aCarton(40,50,60,"fiberboard"); 
              Box aBox;
              aBox=aCarton;
posted @ 2012-09-20 23:32  retacn_yue  阅读(190)  评论(0编辑  收藏  举报