c++lab08随笔

基类

派生类

继承就是从先辈处得到属性和行为特征

1.不必重新描述派生类B的所有特性,只需让它继承类A的特性;      

2. 增加类B与基类A不同的那些特性。 

继承方式:

公用(public):访问权限最高;除派生类外,外部函数也可以直接访问(无论是成员变量还是成员函数)。
私有(private):访问权限最低;只能是该类内部函数互相调用,派生类、外部函数都不能访问。(默认)
保护(protect):访问权限中间;该类内部函数、派生类都能访问,外部类、外部函数不能访问,但是可以通过基类提供的公有成员函数访问。
 
派生类对基类成员的访问形式主要有以下两种:
(1)内部访问 由派生类中新增的成员函数(比如print()函数)对基类继承来的成员的访问
(2)对象访问 在派生类外部(比如main函数里面)通过派生类的对象对从基类继承来的成员的访问
 
(对象只能访问公有成员)
 
 
 class  A {           
      private:     int  X;
      public:      int  Y;
      protected:   int  Z;
 };
 class  B : private  A{
    X    基类中的私有成员不允许派生类继承,(注意是否可以被访问?如果能被访问以什么方式出现在派生类?)
          即在派生类中是不可直接访问的。
    Y    基类中的公有成员在派生类中
          是以私有成员的身份出现的。
    Z    基类中的保护成员在派生类中
          是以私有成员的身份出现的。
 };  
 class  B : public A{
     X   基类中的私有成员不允许派生类继承,
          即在派生类中是不可直接访问的。
     Y   基类中的公有成员在派生类中
          仍以公有成员的身份出现的。
     Z   基类中的保护成员在派生类中
	  仍以保护成员的身份出现的。 
};
  class  B : protected A{
     X  基类中的私有成员不允许派生类继承,
        即在派生类中是不可直接访问的。
     Y  基类中的公有成员在派生类中
        是以保护成员的身份出现的。
     Z  基类中的保护成员在派生类中
	   仍以保护成员的身份出现的。
};
 
派生类构造函数和析构函数的执行顺序

  通常情况下:  当创建派生类对象时:          

        基类的构造函数->派生类的构造函数  

  当撤消派生类对象时:          

        派生类的析构函数->基类的析构函数


派生类

derive(int i ):base(i)  

1、当基类含有带参数的构造函数时,派生类必须定义构造函数,并缀上“:基类名(参数表) ”,以提供把参数传递给基类构造函数的途径,仅仅起参数的传递作用,可能该派生类的函数体为空。

说明: 
    (1)可以将派生类构造函数定义在类的外部,而在类体内只写该函数的声明。

在派生类中声明构造函数的原型:
    derive(int a,int b); 
而在类的外部定义派生类的构造函数:
    derive(int a,int b):base(b) 

   

                        cout<<"调用派生类的构造函数\n"<<endl;

    j=a;

  }

        派生类的一般构造函数

            派生类名(参数总表):基类名(参数表) 
            {
                派生类新增成员的初始化语句
            }    

(2)缺省值=默认值

当构造函数参数表中并不全部使用缺省参数时,具有缺省值的参数必须放置于参数表的最后。

例如:
coordinates (int i, int j=100) 的参数表是对的;
coordinates (int i=100, int j) 的参数表是错的。

若基类使用不带参数的构造函数或带缺省参数的构造函数,则在派生类中定义构造函数时可略去“∶基类(参数表)”;

(3)如果派生类的基类也是一个派生类,每个派生类只需负责其直接基类的构造,依次上溯。

明确函数的成员变量和函数变量

2、析构函数是独立的,

基类函数有无参数跟派生类的析构函数一点关系都没有

3、当派生类中含有对象成员时,其构造函数的一般形式为:

    派生类名(参数总表):基类名(参数表0),对象名成员1(参数表1),…,对象成员名n (参数表n)
   {
      //派生类新增成员的初始化语句 .. 

   }

例如: derived(int i):base(i),d(i)  

 定义派生类对象时,构造函数的执行顺序如下:(若main函数的内容体只有实例化对象的时候就打印构造函数与析构函数

        ·调用基类的构造函数;

        ·调用对象成员的构造函数;

        ·执行派生类的构造函数体。

 撤消对象时,析构函数的调用顺序与构造函数的调用顺序正好相反。
         .调用派生类的析构函数;
         .调用对象成员的析构函数;

         .调用基类的析构函数。


4.3调整基类成员在派生类中的访问属性的其他方法:

4.3.1、如果在派生类中定义了与基类成员同名的成员,则派生类成员覆盖了基类的同名成员

4.3.2、若要访问基类中的f(),可改写成X::f();

4.4.4、访问声明

        问题的提出:

           能否使私有继承的派生类的对象访问基类的公有成员或保护成员?

            解决方法1 :通过公有成员函数间接访问

            解决方法2:使用访问声明

                            例如 A::print; (在B类声明要访问A的print方法,把基类中的数据成员或函数调整为派生类的公有xx)            

                            备注:1、访问声明中只能含不带类型参数的函数名或变量名

                                       2、数据成员也可以使用访问声明

                                       3、访问声明不能改变类成员在基类中原来的性质

                                                例如x在A类是public,那么x在B类中的声明访问也要是public

                                        4、对于基类中的重载函数使用访问声明时要慎重


4.4  多重继承
4.4.1 多重继承的声明
4.4.2 多重继承的构造函数与析构函数

4.4.3 虚基类

4.4.1多重继承额声明

             当一个派生类具有多个基类时,这种派生方法称为多重派生多重继承

            class z:private x,public y(  类z私有继承了类x,公有继承了类y)

4.4.2 多重继承的构造函数与析构函数

 明确单继承与多继承的不同:

            多重继承构造函数的执行顺序与单继承构造函数的执行顺序相同

            析构函数的执行顺序则刚好与构造函数的执行顺序相反

4.4.3 虚基类


构造函数执行顺序:B()-> B1()-> B()-> B2()-> D()

class D:public B1,public B2{ . . .}

提出问题:派生类D中访问共同基类B中的成员a时,可能会产生二义性,怎么解决二义性?

                   解决办法1:在程序中注明B1::a和B2::a

                   解决办法2:使从不同的路径继承的基类的成员在内存中只拥有一个拷贝

虚基类是在派生类的声明,其语法形式如下:

                 class  派生类名:继承方式 virtual 基类名
                  {   … }
                  或
                 class  派生类名: virtual 继承方式 基类名

                  {  … }


构造函数执行顺序:B()-> B1()->  B2()-> D()(只调用B()一次,且是在第一次出现时调用。)

  B(int sa)

  B1(int sa,int sb):B(sa)

  B2(int sa,int sc):B(sa)

  D(int sa,int sb,int sc,int sd): B(sa),B1(sa,sb),B2(sa,sc)


调用顺序:

先调用虚基类的构造函数,

再调用非虚基类的构造函数,

最后调用派生类构造函数;

对于多个虚基类,构造函数的执行顺序仍然是先左后右,自上而下;

对于非虚基类,构造函数的执行顺序仍是先左后右,自上而下;


总结:

公有派生类具有基类的全部功能,凡是基类能够实现的功能,公有派生类都能实现。

我们可以将派生类对象的值赋给基类对象,在用到基类对象的时候可以用其派生类对象代替---基类和派生类对象之间的赋值兼容规则。

说明:所谓赋值仅仅指对基类的数据成员赋值




            


                                                




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值