P5-程序的类层次结构

         这章内容很重要,而且也很多新的概念出现。主要包括:
1,类的继承和派生的基本概念;
2,派生类的构造函数/释放函数与对象的创建;
3,多基派生及虚基类;
4,类层次中的作用域及类转换问题;
5,虚函数、纯虚函数和抽象类
----------------------------------------------------------------------------------------------------------------------
一)类的继承(inheritance)和派生(derivation)的基本概念
        在一个类层次结构中,下一层类(子类)的描述要使用上一层类(父类)的属性和行为,这一特点称为继承;以既有类(基类)为基础导出(定义)新的类(派生类)的过程称为派生。
        派生类格式:
        class 派生类名:派生方式 基类名{
            private:
                新增私有成员声明语句表列
            public:
                新增公开成员声明语句表列
        };
        派生方式有三种:public派生和private派生和protected派生。
        形象起见,类内私有成员可以理解成是一种处于底层的东西,属于只有自己才能知道的秘密,蛇仍保持着独有的私有性,只有本类成员函数和友元函数才可以调用。所以一般情况下,不论哪种派生方式,派生类都是不能访问到基类私有成员的(除非采用特殊方式)。从另一种角度上,也可以说派生类是基类中非私有成员的扩展,不仅可以将基类中的非私有属性/方法变为自己所用,还可以使用自身新增的任何属性/方法。
        private派生,protected派生,public派生就如同把秘密丢到陆海空,埋进地下的秘密只有埋者才会知道,而抛进大海的秘密除了他一个人知道外,海水也知道的(这时海水相当于派生类的方法函数),而放到天空中的秘密地球人都看到了。另外一种方法就是用图示法,共三层,上层表示public,中层表示protected,下层表示private:
        例:D:public C:private B:public A
                D<--C     /B<-A (public)
                              /            (protected)
                        __/                (private)
                从图示可以看出:D的访问权限只有D和C的非private函数;而C对象访问权限为C内非private成员,C内方法函数访问权限为C所有成员及B和A的非private成员。
     例:D:private C:public B: private A
            D      /C<-B     /A
                   /              /
           ___/          __/ 
           从图示可以看出:D类对象访问权限是D非private成员,D类方法函数访问权限是D内所有成员及C和B的非private成员。
二)派生类的构造函数/释放函数与对象的创建
        类层次结构中成员函数是共享的,而数据成员是分别存储的。每一个类对象中,不仅要存储自己类中定义的数据成员,还要存储其先辈中定义的数据成员。但是构造函数与释放函数是不能继承的,为此对派生类必须重新定义构造函数与释放函数。
        派生类对象的创建有两种方式:全部常数参数创建,常数参数+基类对象创建。
#include <iostream.h>
#include <string.h>

class Hard{
protected:
 char bodyname[20];
public:
 Hard(char *bdnm)
 {cout<<"con H"<<endl;
  strcpy(bodyname,bdnm);
 }
 Hard(Hard & abody)
 {cout<<"copy H"<<endl;
  strcpy(bodyname,abody.bodyname);
 }
 void print()
 {cout<<"Body_Name:"<<bodyname<<endl;
 }
};

class Soft{
protected:
 char os[10];
public:
 Soft(char *o)
 {cout<<"con F"<<endl;
  strcpy(os,o);
 }
 Soft(Soft & asoft)
 {cout<<"copy F"<<endl;
  strcpy(os,asoft.os);
 }
 void print()
 {cout<<"os:"<<os<<endl;
 }
};

class Language{
protected:
 char lang[15];
public:
 Language(char *lg)
 {cout<<"con L"<<endl;
  strcpy(lang,lg);
 }
 Language(Language & aLanguage)
 {cout<<"copy L"<<endl;
  strcpy(lang,aLanguage.lang);
 }
 void print()
 {cout<<"lange:"<<lang<<endl;
 }
};

class System:public Hard,public Soft,public Language{
protected:
 char owner[10];
public:
 System(char *ow, char *bn, char *o, char *lg):Hard(bn),Soft(o),Language(lg)
 {cout<<"con S"<<endl;
  strcpy(owner,ow);
 }
 System(char *ow,Hard abody, Soft asoft, Language aLanguage):Hard(abody),Soft(asoft),Language(aLanguage)
 {cout<<"copy S"<<endl;
  strcpy(owner,ow);
 }
 void print()
 {cout<<"owner:"<<owner<<endl
      <<"hard:"<<bodyname<<endl
   <<"soft:"<<os<<endl
   <<"Language:"<<lang<<endl;
 }
};

void main()
{System bsystem("Wang","IBM PC","PC DOS","Ture BASIC");
 bsystem.print();
 cout<<"OK!"<<endl<<endl;
Hard abody("AST 386 sx/16");
Soft asoft("PC DOS");
Language aLanguage("Borland C++");
cout<<endl<<endl;

//System asystem("Zhang",abody,asoft,aLanguage); //copyL,copyF,copyH
//System asystem("Zhang",abody,asoft,"Borland C++"); //conL,copyF,copyH
System asystem("Zhang",abody,"PC DOS",aLanguage); //copyL,conF,copyH

asystem.print();

}
        该示例中包括了两种创建方法,当派生类对象创建时,首先扫描参数列表见红体字,如果其中未发现基类对象,将转到绿色字部分先执行基类构造函数,再执行派生类构造函数进行初始化。而如果在形参中发现基类对象,则会从右到左根据情形来调用基类的复制构造函数或构造函数(为什么从右到左呢,因为扫描从左到右的,扫描到最后才能确定参数列表中有多少基类对象参数,按栈的FILO规则,调用基类复制构造函数必然是从右到左,,这是我个人的理解),然后再加到绿体字部分执行基类函数的构造函数;最后再执行派生类构造函数进行初始化。
三)多基派生及虚基类;
        

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值