[C ++]クラスの継承と派生

[C ++]クラスの継承と派生

  继承性是面向对象程序设计的第二大特性,它允许在既有类的基础上创建新类,新类可以继承既有类的数据成员和成员函数,可以添加自己特有的数据成员和成员函数,还可以对既有类中的成员函数重新定义。利用类的继承和派生实现了更高层次的代码可重用性,符合现代软件开发的思想。

  C++语言同时支持单一继承和多重继承。单一继承是指派生类只从一个基类继承而来;相应的,多重继承指派生类同时从两个或更多的基类继承而来。java只支持单一继承。

1.派生クラス

派生クラスの定義形式は次のとおりです。

  class <派生类名>:[继承方式]<基类名1>

                             [,[继承方式]<基类名2>,...,[继承方式]<基类名n>]

  {

          <派生类新增的数据成员和成员函数定义>

  };

説明:

  (1)定义派生类关键字可以是class或者是struct,两者区别是:用class定义派生类,默认的继承方式是private,用struct定义派生类,默认的继承方式为public。新增加的成员默认属性也是class对应private属性,struct对应public属性。

  (2)基类不能被派生类继承的两类函数是构造函数和析构函数。

2.3つの継承メソッドの下で派生クラスの基本クラスメンバーの属性にアクセスします

ここに画像の説明を挿入
次のコードを使用して、簡単に理解してください。

#include "stdafx.h"
#include<iostream>
using namespace std;

class Base
{
    
    
private:
    int priData;
protected:
    int proData;
public:
    int pubData;
};

class D1:private Base//私有继承
{
    
    
    void f1()
    {
    
    
        //priData=1;//基类private成员在派生类中不可直接访问
        proData=2;//基类的protected成员在派生类中为private访问属性
        pubData=3;//基类的public成员在派生类中为private访问属性
    }
};

class D2:protected Base//保护继承
{
    
    
    void f2()
    {
    
    
        //priData=1;//基类private成员在派生类中不可直接访问
        proData=2;//基类的protected成员在派生类中为protected访问属性
        pubData=3;//基类的public成员在派生类中为protected访问属性
    }
};

class D3:public Base//公有继承
{
    
    
    void f3()
    {
    
    
        //priData=1;//基类private成员在派生类中不可直接访问
        proData=2;//基类的protected成员在派生类中为protected访问属性
        pubData=3;//基类的public成员在派生类中为public访问属性
    }
};

int main()
{
    
    
    Base obj;
    //obj.priData=1;//对象不可访问Base类中private成员
    //obj.proData=2;//对象不可访问Base类中protected成员
    obj.pubData=3;
    D1 objD1;
    //objD1.pubData=3;//private属性,不可访问
    D2 objD2;
    //objD2.pubData=3;//protected属性,不可访问
    D3 objD3;
    objD3.pubData=3;//public属性,可以访问
    return 0;
}

基本クラスのプライベートメンバー関数は、派生クラスのメンバー関数から直接アクセスすることはできませんが、派生クラスのメンバー関数は、基本クラスの継承された関数を呼び出すことにより、これらのメンバーに間接的にアクセスできます。基本クラスの関数が継承された後も派生クラスのパブリックメンバーである場合は、派生クラスオブジェクトを介して直接呼び出すことができます。
まず、クラスメンバーのアクセス属性と機能を確認します。

属性関数privateへのアクセスは、このクラスのメンバー関数とフレンド関数へのアクセスのみを許可し、他の関数からはアクセスできません。protectedこのクラスのメンバー関数とフレンド関数、およびその派生クラスのメンバー関数へのアクセスを許可します。パブリックは許可します。両方のクラスメンバー関数アクセスは、クラス外の他の関数もアクセスできるようにします
さて、コードを通して理解し続けてください:

#include "stdafx.h"
#include<iostream>
using namespace std;

class Base
{
    
    
private:
    int priData;
protected:
    int proData;
public:
    int pubData;
//在类的定义中不能对数据成员进行初始化
    void SetData()//为基类中的数据成员赋值
    {
    
    
        priData=100;
        proData=200;
        pubData=300;
    }
    void Print()
    {
    
    
        cout<<"priData="<<priData<<endl;
        cout<<"proData="<<proData<<endl;
        cout<<"pubData="<<pubData<<endl;
    }
};

class Derived:public Base
{
    
    
public:
    void ChangeData()
    {
    
    
        SetData();
        proData=12;//在派生类的成员函数类可以访问基类的非私有成员                   
    }
};

int main()
{
    
    
    Base b;
    b.SetData();
    b.Print();

    Derived d1;
    d1.ChangeData();
    d1.pubData=13;
    d1.Print();
    
    return 0;
}
  程序运行结果如下:

ここに画像の説明を挿入

3.派生クラスのコンストラクタとデストラクタ

  在定义一个派生类的对象时,在派生类中新增加的数据成员当然用派生类的构造函数初始化,但是对于从基类继承来的数据成员的初始化工作就必须由基类的构造函数完成,这就需要在派生类的构造函数中完成对基类构造函数的调用。同样,派生类的析构函数值能完成派生类中新增加数据成员的扫尾、清理工作,而从基类继承来的数据成员的扫尾工作也应有基类的析构函数完成。由于析构函数不能带参数,因此派生类的析构函数默认直接调用了基类的析构函数。

派生クラスコンストラクターの定義形式は次のとおりです。
<派生クラス名>(<正式なパラメーターテーブルの合計>):<基本クラス名1>(<パラメーターテーブル1>)、

   <基类名2>(<参数表2>),[...,<基类名n>(<参数表n>),其他初始化项>]

   {

           [<派生类自身数据成员的初始化>]

    }

  说明:(1)总形式表给出派生类构造函数中所有的形式参数,作为调用基类带参构造函数的实际参数以及初始化本类数据成员的参数;

  (2)一般情况下,基类名后面的参数表中的实际参数来自前面派生类构造函数形式参数总表,当然也可能是与前面形式参数无关的常量;

  (3)在多层次继承中,每一个派生类只需要负责向直接基类的构造函数提供参数;如果一个基类有
  多个派生类,则每个派生类都要负责向该积累的构造函数提供参数。

1.単一継承

#include"stdafx.h"
#include<iostream>
using namespace std;

class Other
{
    
    
public:
    Other()
    {
    
    
        cout<<"constructing Other class"<<endl;
    }
    ~Other()
    {
    
    
        cout<<"destructing Other class"<<endl;
    }
};

class Base
{
    
    
public:
    Base()
    {
    
    
        cout<<"constructing Base class"<<endl;
    }
    ~Base()
    {
    
    
        cout<<"destructing Base class"<<endl;
    }
};

class Derive:public Base
{
    
    
private:
    Other ot;
public:
    Derive()
    {
    
    
        cout<<"constructing Derive class"<<endl;
    }
    ~Derive()
    {
    
    
        cout<<"destructing Derive class"<<endl;
    }
};

int main()
{
    
    
    Derive d;

    return 0;
}

プログラムの結果は次のとおりです。
ここに画像の説明を挿入

可以看到定义派生类对象时,构造函数的调用顺序:

  a.先调用基类的构造函数

  b.然后调用派生类对象成员所属类的构造函数(如果有对象成员)

  c.最后调用派生类的构造函数

  析构函数的调用顺序正好与构造函数调用顺序相反。

2.多重継承

#include"stdafx.h"
#include<iostream>
using namespace std;

class Grand
{
    
    
    int g;
public:
    Grand(int n):g(n)
    {
    
    
        cout<<"Constructor of class Grand g="<<g<<endl;
    }
    ~Grand()
    {
    
    
        cout<<"Destructor of class Grand"<<endl;
    }
};

class Father:public Grand
{
    
    
    int f;
public:
    Father(int n1,int n2):Grand(n2),f(n1)
    {
    
    
        cout<<"Constructor of class Father f="<<f<<endl;
    }
    ~Father()
    {
    
    
        cout<<"Destructor of class Father"<<endl;
    }
};

class Mother
{
    
    
    int m;
public:
    Mother(int n):m(n)
    {
    
    
        cout<<"Constructor of class Mother m="<<m<<endl;
    }
    ~Mother()
    {
    
    
        cout<<"Destructor of class Mother"<<endl;
    }
};

class Son:public Father,public Mother
{
    
    
    int s;
public:
    Son(int n1,int n2,int n3,int n4):Mother(n2),Father(n3,n4),s(n1)
    {
    
    
        cout<<"Constructor of class Son s="<<s<<endl;
    }
    ~Son()
    {
    
    
        cout<<"Destructor of class Son"<<endl;
    }
};

int main()
{
    
    
    Son s(1,2,3,4);
    return 0;
}

プログラムの結果は次のとおりです。
ここに画像の説明を挿入

  可以看到,与单一继承不同的是:在多重继承中,派生类有多个平行的基类,这些处于同一层次的基类构造函数的调用顺序,取决于声明派生类时所指定的各个基类的顺序,而与派生类构造函数的成员初始化列表中调用基类构造函数的顺序无关。

おすすめ

転載: blog.csdn.net/wmy0536/article/details/106006006