派生类的构造函数和析构函数

      基类都有显式的或隐式的构造函数 和析构函数。 当创 建一个 派生类对象时 , 如何 调用基类的构造函数对基类数据初始化 , 以及在撤消派生类对象时 , 又如何调用基类的析构函数来对基类对象的数据成员进行善后处理 , 这是本节所要讨论的问题。
 

1、派生类构造函数和析构函数的执行顺序
 

         通常情况下 , 当创建派生类对象时 , 首先执 行基类 的构 造函数 , 随 后再 执行派 生类 的构造函数 ; 当撤消派 生类 对 象 时 , 则 先 执 行 派 生类 的 析 构 函 数 , 随 后 再 执 行基 类 的 析 构函数。
下列程序的运行结果 , 反映了基类和派生类的构造函数及析构函数的执行顺序。
 

#include <iostream>
using namespace std;
class base
{
public:
    base()
    {
        cout << "基类构造函数\n";
    } // 基类的构造函数
    ~base()
    {
     cout << "基类析构函数\n";

    } // 基类的析构函数
};
class derive : public base
{
public:
    derive() // 派生类的构造函数
    {
        cout << "派生类构造函数 \n";
    }
    ~derive() // 派生类的析构函数
    {
        cout << "派生类析构函数\n";
    }
};
main ( )
{
derive op;
return 0 ;
}

结果:

 从程序运行的结果可以看出 :

构造函数的调用严格地按照先调用基类的构造函数 , 后调用派生类的构造函数的顺序执行。

析构函数的调用顺序与构造函数的调用顺序正好相反 , 先调用派生类的析构函数 , 后调用基类的析构函数。
 

2、派生类构造函数和析构函数的构造规则

        当基类的构造函数没有参数 , 或没有显式定义构造函数时 , 派生类可以不向基类传递参数 , 甚至可以不定义构造函数。 例 4 .7 的程序就是由于基类的构造函数没有参数 , 所以派生类没有向基类传递参数。派生类不能继承基类中的构造函数 和析 构函 数。 当基 类含有 带参 数的 构造函 数时 ,派生类必须定义构造函数 , 以提供把参数传递给基类构造函数的途径。
【1】、在 C + + 中 , 派生类构造函数的一般格式为 :
派生类构造函数名(参数表) : 基类构造函数名( 参数表)
{
/ / …
}
其中基类构造函数的参数 , 通常来源于派生类构造函数的参数表 , 也可以用常数值

下面的程序说明如何传递一个参数给派生类的构造函数和传递一个参数给基类的构造函数。
 

#include <iostream>
using namespace std;
class base
{
int i;
public:
    base(int n)
        {
        cout << "基类的构造函数\n";
        i = n;
        }
    ~base()
        {
            cout << "基类的析构函数\n";
        }
void showi()
{
    cout << "i="<<i << endl;
}
};
class derive : public base
{
int j;
public:
    derive(int n, int m) : base( m) // 定义派生类构造函数时,缀上基类的构造函数
    {
        cout << "派生类构造函数"<< endl;
        j = n;
     }
    ~derive()
    {
          cout << "派生类的析构函数"<< endl;
    }
    void showj()
    {
        cout << "j="<<j << endl;
    }
};
main ( )
{
derive obj( 30, 40) ;
obj .showi( ) ;
obj .showj( ) ;
return 0 ;
}

 结果:

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


派生类构造函数名(参数表) : 基类构造函数名( 参数表) , 对象成员名 1 (参数表) , … ,
对象成员名 n (参数表)
{ /
/ …
}

在定义派生类对象时 , 构造函数的执行顺序如下 :
· 基类的构造函数
· 对象成员的构造函数
· 派生类的构造函数
撤消对象时 , 析构函数的调用顺序与构造函数的调用顺序正好相反。


下面这个程序说明派生类构造函数和析构函数的执行顺序。
 

#include <iostream>

using namespace std;
class base
{
int x;
public:
base(int i)
{
x = i;
cout << "基类的构造函数 \n";
}
~base( )
{
    cout << "基类的析构函数\n";
}
void show( )
{
    cout << "x = " << x << endl;}
};

class derived: public base
{
    base d; // d 为基类对象 , 作为派生类的对象成员
public:
 derived(int i) : base(i) , d( i) //派生类的构造函数,缀上基类构造函数和对象成员构造函数
    {
       cout << "派生类的构造函数\n";
    }
  ~derived()
    {
        cout << "派生类的析构函数 \n";}
    };
main ( )
{
derived obj(5 ) ;
obj .show( ) ;
return 0 ;
}

结果:

小结:
(1 ) 当基类构造函数不带参数时 , 派生类不一定需要定义构造函数 , 然而 当基类的 构
造函数哪怕只带有一个参数 , 它所有的派生类都必须定义构造函数 , 甚至所定义的派生类
构造函数的函数体可能为空 , 仅仅起参数的传递作用。

(2 ) 若基类使用缺省构造 函数或 不带 参数的 构造 函数 , 则 在派生 类中 定义构 造函 数
时可略去 “ ∶基类构造函数名(参数表)”; 此时若 派生类 也不 需要构 造函 数 , 则可不 定义 构
造函数。
(3 ) 如果派生类的基类也是一个派生类 , 则每个派生类只需负责其 直接基类 的构造 ,
依次上溯。
· 105 ·
(4 ) 由于析构函数是不带参 数的 , 在 派生类 中是 否要定 义析 构函 数与它 所属 的基 类
无关 , 故基类的 析 构 函 数 不 会 因 为 派 生 类 没 有 析 构 函 数 而 得 不 到 执 行 , 它 们 各 自 是 独
立的。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值