op3.setc(3 ) ; op3.show ( ) }
(8.2.3
多重继承及派生类的构造函数和析构函数) 例 题
例5 派生类中的构造函数和析构函数的调用顺序 # include
CBase1(int a)
{x=a ;cout<<”调用了基类1的构造函数!\\n” ;} ~CBase1 ( void )
{ cout<<”调用了基类1的析构函数!\\n” ;} };
class CBase2 { int y ; public :
CBase2 (int a)
{y=a :cout<<”调用了基类2的构造函数!\\n” ;} ~CBase2 ( void )
{ cout<<”调用了基类2的析构函数!\\n” ;} };
class CDerived :public CBase1 , public CBase2 //A 此处基类顺序影响构造函数的调用顺序。 { int z ; public:
CDerived ( int a , int b ,int c):CBase1(a) ,CBase2(b) //B初始化基类成员 { z=c ; cout<<”调用了派生类的构造函数!\\n” ;} ~ CDerived(void)
{ cout<<”调用了派生类的析造函数!\\n” ; } };
void main ( void )
{CDerived d (2, 4 , 6) ;} 执行结果:
调用了基类1的构造函数! 调用了基类2的构造函数! 调用了派生类的构造函数! 调用了派生类的析造函数! 调用了基类2的析构函数! 调用了基类1的析构函数!
7)如果派生类中包含对象成员,则创建派生类对象时,C++规定构造函数的调用次序为: 基类的构造函数、对象成员的构造函数、派生类的构造函数。
11
如果,此时基类中有对象成员,调用基类的构造函数之前还要先调用基类对象成员的构造函数,调用次序与前述类同。
在初始化成员列表中,对象成员采用的是对象名,而对基类的初始化使用的是基类的类名,即基类的构造函数名。
调用顺序如下图所示:
基类的基类的构造函数
基类对象成员的构造函
基类的构造函数
派生类对象的构造函数
派生类的构造函数
例6 派生类中包含对象成员,将前例中的派生类的定义作如下的修改: # include
CBase1(int a)
{x=a ;cout<<”调用了基类1的构造函数!\\n” ;} ~CBase1 ( void )
{ cout<<”调用了基类1的析构函数!\\n” ;} };
class CBase2 { int y ; public :
CBase2 (int a)
{y=a :cout<<”调用了基类2的构造函数!\\n” ;} ~CBase2 ( void )
{ cout<<”调用了基类2的析构函数!\\n” ;} };
class CDerived :public CBase1 , public CBase2 { int z ;
CBase 1 b1 ,b2 ; public:
CDerived ( int a , int b , int c ) :CBase1(a) ,CBase2(b) ,b1(20) ,b2(a*b) { z=c ; cout<<”调用了派生类的构造函数!\\ n “ ;} ~CDerived (void )
{ cout<<” 调用了派生类的析构函数!\\ n “ ;} };
void main ( void )
{CDerived d (2, 4 , 6) ;}
12
如果其它内容不变,则程序输出: 调用了基类1的构造函数! 调用了基类2的构造函数! 调用了基类1的构造函数! 调用了基类1的构造函数! 调用了派生类的构造函数! 调用了派生类的析造函数! 调用了基类1的析构函数! 调用了基类1的析构函数! 调用了基类2的析构函数! 调用了基类1的析构函数!
8) 如果基类A的派生类为B,B又派生了C,则在对B进行初始化之前,必须对它的基类A进行初始化,通常是通过B的构造函数实现。但是不能通过C的构造函数实现。即一个类的构造函数只能对它的直接基类的构造函数传递实参。对于更多层继承关系,都可按这种方式递归进行。
例7多层继承的基类成员的初始化 # include
{ x=a ;cout<<”调用了类A的构造函数\\n” ;} };
class B :public A { protected :
int y ; public: B ( int a ,int b) :A(a)
{ y=b ;cout<<”调用了类B的构造函数\\n” ;} };
class c :public B { protected: int z ; public:
C ( int a ,int b, int c) :B(a,b)
{ z=c ;cout<<”调用了类C的构造函数\\n” ;} };
void main ( ) {A a(1) ;
13
B b (10 ,20) ;
C c(100 ,200,300) ; }
执行结果:
调用了类A的构造函数 调用了类A的构造函数 调用了类B的构造函数 调用了类A的构造函数” 调用了类B的构造函数 调用了类C的构造函数
例8:求圆柱的体积 #define PI 3.1415926 # include
CCircle ( float R) { r = R ;} float Getr ( void ) {return r ;} };
class Crectangle
{ float l , w ; //矩形的长和宽 public :
Crectangle ( float L) {l=L ;}
float Getl ( void ) {return l ;} };
class CColumn :public CCircle , public Crectangle { double v ; //圆柱体的体积 public:
CColumn (float L ,float w) :CCircle(W/2),Crectangle(L) { }
void Volumn(void)
{v=PI*Getr()*Getr()*Get1() ; }
void ShowVolumn(void )
{cout<<”Volumn=”< void main (void) {CColumn col (7.5,4) ; col.Volumn( ) ; col.ShowVolumn(); 14 } 执行结果: Volumn=94.2478 例9 (program 8-3 p260) CA CB CC CD 类之间的继承关系 #include class CB{ int b; public: CB(int n){ b=n; cout<<\ ~CB(){cout<<\}; class CC: public CA { int c; public: CC(int n1,int n2):CA(n2) { c=n1; cout<<\ ~CC(){cout<<\}; class CD:public CB,public CC{ int d; public: CD(int n1,int n2,int n3,int n4):CC(n3,n4),CB(n2) { d=n1; cout<<\ ~CD(){cout<<\}; void main(void) { CD CDobj(2,4,6,8); } 15