C++_派生类的构造函数和析构函数
派生类的构造函数和析构函数
基类的构造函数和析构函数不能被继承,一般派生类要加入自己的构造函数。
1. 派生类构造函数和析构函数的执行顺序
通常情况下,当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数;
当撤消派生类对象时,则先执行派生类的析构函数,随后再执行基类的析构函数。
例 基类和派生类的构造函数及析构函数的执行顺序。
#include<iostream.h>
class Base{
public:
Base(){ cout<<"Constructing base class\n"; }
//基类的构造函数
~Base(){ cout<<"Destructing baes class\n"; }
//基类的析构函数
};
class Derive:public Base{
public:
Derive(){cout<<"Constructing derived class\n";}
//派生类的构造函数
~Derive(){cout<<"Destructing derived class\n";}
//派生类的析构函数
};
main()
{ Derive op; return 0; }
2. 派生类构造函数和析构函数的构造规则
当基类的构造函数没有参数,或没有显式定义构造函数时,派生类可以不向基类传递参数,甚至可以不定义构造函数;
当基类含有带参数的构造函数时,派生类必须定义构造函数,以提供把参数传递给基类构造函数的途径。
在C++中,派生类构造函数的一般格式为:
派生类名(参数总表):基类名(参数表)
{
// 派生类新增成员的初始化语句
}
基类构造函数的参数,通常来源于派生类构造函数参数总表,也可以用常量值
例 当基类含有带参数的构造函数时, 派生类构造函数的构造方法
#include<iostream.h>
class Base {
public:
Base(int n) { //基类的构造函数
cout<<"Constructing base class\n";
i = n;
}
~Base() { //基类的析构函数
cout<<"Destructing base class\n";
}
void showi() { cout<<i<<endl; }
private:
int i;
};
class Derive :public Base{
public:
Derive(int n,int m):Base(m) { // 定义派生类构造函数时,缀上基类的构造函数
cout<<"Constructing derived class"<<endl;
j=n;
}
~Derive() //派生类的析构函数
{ cout<<"Destructing derived class"<<endl; }
void showj() { cout<<j<<endl;}
private:
int j;
};
main(){
Derive obj(50,60);
obj.showi();
obj.showj();
return 0;
}
3. 内嵌对象成员时
派生类中含有内嵌对象成员时,其构造函数一般形式为:
派生类名(参数总表):基类名(参数表1),内嵌对象名1(内嵌对象参数表1),…,内嵌对象名n(内嵌对象参数表n)
{
// 派生类新增成员的初始化语句
}
在定义派生类对象时,构造函数的执行顺序如下:
- 调用 基类 的构造函数;
- 调用 内嵌对象成员(子对象类) 的构造函数(有多个对象成员时,调用顺序由它们在类中声明的顺序确定) ;
- 派生类 的构造函数体中的内容
撤消对象时,析构函数的调用顺序与构造函数的调用顺序正好相反。
例 内嵌对象成员时派生类构造函数和析构函数的执行顺序
#include<iostream.h>
class Base {
int x;
public:
Base(int i) { //基类的构造函数
x=i;
cout<<"Constructing base class\n";
}
~Base() //基类的析构函数
{ cout<<"Destructing base class\n"; }
void show()
{ cout<<" x=" <<x<<endl; }
};
class Derived: public Base {
Base d; //d为基类对象,作为派生类的对象成员
public:
Derived(int i): Base(i),d(i) {
//派生类的构造函数,缀上基类构造函数和对象成员构造函数
cout<<"Constructing derived class\n";
}
~Derived() //派生类的析构函数
{ cout<<"Destructing derived class\n"; }
};
main(){
Derived obj(123);
obj.show();
return 0;
}
需要注意的几点:
- 当基类构造函数不带参数时,派生类可不定义构造函数,但基类构造函数带有参数,则派生类必须定义构造函数
- 若基类使用缺省构造函数或不带参数的构造函数,则在派生类中定义构造函数时可略去“:基类构造函数名(参数表)”
- 如果派生类的基类也是一个派生类,每个派生类只需负责其直接基类的构造,依次上溯。
- 由于析构函数是不带参数的,在派生类中是否定义析构函数与它所属的基类无关,基类的析构函数不会因为派生类没有析构函数而得不到执行,基类和派生类的析构函数是各自独立的。
class base{
int i;
public:
base(int n)
{ cout<<"Constructing base class\n"; i=n; }
void showi()
{ cout<<i<<"\n"; }
};
class derived: public base{
int j;
public:
derived(int n):base(n){
cout<<"constructing derived class\n";
j=0;
}
void showj()
{ cout <<j<<"\n"; }
};
例:说明派生类构造函数和析构函数的构造规则
#include<iostream.h>
class First{
private:
int a,b;
public:
First() {a=0;b=0;}
First(int x,int y) { a=x;b=y;}
~First(){ }
void print(){ cout<<"\n a="<<a<<" b="<<b; }
};
class Second: public First{
private:
int c,d;
public:
Second(): First(1,1)
{ c=0; d=0; }
Second(int x,int y): First(x+1,y+1)
{ c=x; d=y; }
Second(int x,int y,int m,int n): First(m,n)
{ c=x; d=y; }
~Second(){ }
void print() { //覆盖基类同名成员函数
First∷print();
cout<<" c="<<c<<" d="<<d;
}
};
class Third: public Second{
private:
int e;
public:
Third() { e=0; }
Third(int x,int y,int z): Second(x,y)
{ e=z; }
Third(int x,int y,int z,int m,int n): Second(x,y,m,n)
{ e=z; }
~Third(){ }
void print() { //覆盖基类同名成员函数
Second∷print();
cout<<" e="<<e;
}
};
main(){
First obj0;
obj0.print();
Second obj1;
obj1.print();
Second obj2(10,10,20,20);
obj2.print();
Second obj3(10,10);
obj3.print();
Third obj4;
obj4.print();
Third obj5(10,10,20);
obj5.print();
Third obj6(100,100,200,50,50);
obj6.print();
return 0;
}
a=0 b=0
a=1 b=1 c=0 d=0
a=20 b=20 c=10 d=10
a=11 b=11 c=10 d=10
a=1 b=1 c=0 d=0 e=0
a=11 b=11 c=10 d=10 e=20
a=50 b=50 c=100 d=100 e=200

浙公网安备 33010602011771号