1、派生類的構(gòu)造函數(shù):
派生類的對(duì)象的數(shù)據(jù)結(jié)構(gòu)是由基類中說明的數(shù)據(jù)成員和派生類中說明的數(shù)據(jù)成員共同構(gòu)成。
構(gòu)造函數(shù)不能被繼承,因此派生類的構(gòu)造函數(shù)必須通過調(diào)用基類的構(gòu)造函數(shù)來初始化基類對(duì)象。所以在定義派生類的構(gòu)造函數(shù)時(shí)除了對(duì)自己的數(shù)據(jù)成員進(jìn)行初始化外,還必須負(fù)責(zé)調(diào)用基類構(gòu)造函數(shù)使基類的數(shù)據(jù)成員得以初始化。如果派生類中還有子類對(duì)象,還應(yīng)包含對(duì)子類 對(duì)象初始化的構(gòu)造函數(shù)。
• 一般格式:
< 派生類名 > ( < 派生類構(gòu)造函數(shù)總參數(shù)表 > ): < 基類構(gòu)造函數(shù) >(< 參數(shù)表 1>),< 子對(duì)象名 >(< 參數(shù)表 2>)
{
< 派生類匯總數(shù)據(jù)成員初始化 >
};
• 派生類構(gòu)造函數(shù)的調(diào)用順序:
• 基類的構(gòu)造函數(shù)
• 子對(duì)象類的構(gòu)造函數(shù)
• 派生類的構(gòu)造函數(shù)
例如:分析下列程序的輸出結(jié)果:
#include
class A
{
public:
A()
{a=0;cout<<”A's default constructor called.\n”;}
A(int I)
{a=I;cout<<”A's constructor called.\n”;}
~A()
{cout<<”A's destructor called.\n”;}
void Print()
{ cout<
int Geta(){return a;}
private:
int a;
};
class B:public A
{
public:
B()
{b=0;cout<<”B's default constructor called.\n”;}
B(int I,int j,int k);
~B()
{cout<<”B's destructor called.\n”;}
void Print();
Private:
int b;
A aa;
};
B::B(int I,int j,int k):A(i),aa(j)
{
b=k;
cout<<”B's constructor called.\n”;
}
void B::Print()
{
A::Print();
cout<
}
void main()
{
B bb[2];
bb[0]=B(1,2,5); // 注:給已建立的兩個(gè)對(duì)象賦值,系統(tǒng)要建立兩個(gè)
bb[1]=B(3,4,7); 匿名對(duì)象,通過構(gòu)造函數(shù)對(duì)它初始化,并將
for (int I=0;I<2;I++) 其賦值給已定義的左值對(duì)象,再調(diào)用析構(gòu)
bb[I].Print(); 函數(shù)將匿名對(duì)象刪除。
}
執(zhí)行該程序的輸出結(jié)果:
A'default constructor called.
A'default constructor called.
B'default constructor called.
A'default constructor called.
A'default constructor called.
B'default constructor called.
A' constructor called. // 匿名對(duì)象的構(gòu)造
A' constructor called.
B' constructor called.
A'destructor called. // 匿名對(duì)象的析構(gòu)
A'destructor called.
B'destructor called.
A' constructor called. // 匿名對(duì)象的構(gòu)造
A' constructor called.
B' constructor called.
A'destructor called. // 匿名對(duì)象的析構(gòu)
A'destructor called.
B'destructor called.
1 , 5 , 2
3 , 7 , 4
B'destructor called.
A'destructor called.
A'destructor called.
B'destructor called.
A'destructor called.
A'destructor called.
2、析構(gòu)函數(shù):當(dāng)對(duì)象被刪除時(shí),派生類的析構(gòu)函數(shù)被執(zhí)行。由于析構(gòu)函數(shù)也不能被繼承,因此在執(zhí)行派生類的析構(gòu)函數(shù)時(shí),基類的析構(gòu)函數(shù)也將被調(diào)用。執(zhí)行順序是先執(zhí)行派生類的析構(gòu)函數(shù),再執(zhí)行基類的析構(gòu)函數(shù),其執(zhí)行順序與執(zhí)行構(gòu)造函數(shù)時(shí)的順序相反。
例如:分析下列程序的輸出結(jié)果:
#include
class M
{
public:
M(){m1=m2=0;}
M(int I,int j){m1=I;m2=j;}
Void Print(){cout<
~M(){cout<<”M's destructor called.\n”;}
private:
int m1,m2;
}
class N: public M
{
public:
N(){n=0;}
N(int I,int j,int k);
Void Print()
{
M::Print();
Cout<
~N(){cout<<”N's Destructor called.\n”;}
private:
int n;
};
N::N(int I,int j,int k):M(I,j),n(k)
{}
void main()
{
N n1(5,6,7),n2(-2,-3,-4);
n1.Print();
n2.Print();
}
運(yùn)行結(jié)果: 5,6,7
-2,-3,-4
N's destructor called.
M's destructor called.
N's destructor called.
M's destructor called.
3、 派生類構(gòu)造函數(shù)使用中應(yīng)注意的問題:
• 派生類構(gòu)造函數(shù)的定義中可以省略對(duì)其基類構(gòu)造函數(shù)的調(diào)用,其條件是在基類中必須有缺省的構(gòu)造函數(shù),或者根本沒有定義構(gòu)造函數(shù)。
例如:分析下列程序的輸出結(jié)果:
#include
class A
{
public:
A(){a=0;}
Void print() {cout<
private:
int a;
};
class B:public A
{
public:
B(){b1=b2=0;}
B(int I){b1=I;b2=0;}
B(int I,int j,int k):A(i),b1(j),b2(k){}
Void print()
{A::print();
cout<
}
private:
int b1,b2;
};
void main()
{
B d1;
B d2(5);
B d3(4,5,6);
d1.print();
d2.print();
d3.print();
}
結(jié)果: 0,0,0
0,5,0
4,5,6
• 當(dāng)基類的構(gòu)造函數(shù)使用一個(gè)或多個(gè)參數(shù)時(shí),則派生類必須定義構(gòu)造函數(shù),提供將參數(shù)傳遞給基類構(gòu)造函數(shù)的途徑。在有的情況下,派生類構(gòu)造函數(shù)的函數(shù)體可能為空,僅起到參數(shù)傳遞的作用。
Class B
{
public:
B(int I,int j){b1=I;b2=j;}
Privte:
Int b1,b2;
};
class D:public B
{
public:
D(int I,int j,int k,int l,int m);
Private:
Int d1;
B bb;
};
D::D(int I,int j,int k,int l,int m):B(I,j),bb(k,l)
{d1=m;}
分析:派生類的 構(gòu)造函數(shù)有 5 個(gè)參數(shù),其中前兩個(gè)參數(shù)傳遞給基類 B 的構(gòu)造函數(shù),接著兩個(gè)參數(shù)傳遞給子對(duì)象 bb 的類 B 的構(gòu)造函數(shù),最后一個(gè)參數(shù)是傳遞給派生類 D 的數(shù)據(jù)成員 d1 。
派生類的對(duì)象的數(shù)據(jù)結(jié)構(gòu)是由基類中說明的數(shù)據(jù)成員和派生類中說明的數(shù)據(jù)成員共同構(gòu)成。
構(gòu)造函數(shù)不能被繼承,因此派生類的構(gòu)造函數(shù)必須通過調(diào)用基類的構(gòu)造函數(shù)來初始化基類對(duì)象。所以在定義派生類的構(gòu)造函數(shù)時(shí)除了對(duì)自己的數(shù)據(jù)成員進(jìn)行初始化外,還必須負(fù)責(zé)調(diào)用基類構(gòu)造函數(shù)使基類的數(shù)據(jù)成員得以初始化。如果派生類中還有子類對(duì)象,還應(yīng)包含對(duì)子類 對(duì)象初始化的構(gòu)造函數(shù)。
• 一般格式:
< 派生類名 > ( < 派生類構(gòu)造函數(shù)總參數(shù)表 > ): < 基類構(gòu)造函數(shù) >(< 參數(shù)表 1>),< 子對(duì)象名 >(< 參數(shù)表 2>)
{
< 派生類匯總數(shù)據(jù)成員初始化 >
};
• 派生類構(gòu)造函數(shù)的調(diào)用順序:
• 基類的構(gòu)造函數(shù)
• 子對(duì)象類的構(gòu)造函數(shù)
• 派生類的構(gòu)造函數(shù)
例如:分析下列程序的輸出結(jié)果:
#include
class A
{
public:
A()
{a=0;cout<<”A's default constructor called.\n”;}
A(int I)
{a=I;cout<<”A's constructor called.\n”;}
~A()
{cout<<”A's destructor called.\n”;}
void Print()
{ cout<
int Geta(){return a;}
private:
int a;
};
class B:public A
{
public:
B()
{b=0;cout<<”B's default constructor called.\n”;}
B(int I,int j,int k);
~B()
{cout<<”B's destructor called.\n”;}
void Print();
Private:
int b;
A aa;
};
B::B(int I,int j,int k):A(i),aa(j)
{
b=k;
cout<<”B's constructor called.\n”;
}
void B::Print()
{
A::Print();
cout<
}
void main()
{
B bb[2];
bb[0]=B(1,2,5); // 注:給已建立的兩個(gè)對(duì)象賦值,系統(tǒng)要建立兩個(gè)
bb[1]=B(3,4,7); 匿名對(duì)象,通過構(gòu)造函數(shù)對(duì)它初始化,并將
for (int I=0;I<2;I++) 其賦值給已定義的左值對(duì)象,再調(diào)用析構(gòu)
bb[I].Print(); 函數(shù)將匿名對(duì)象刪除。
}
執(zhí)行該程序的輸出結(jié)果:
A'default constructor called.
A'default constructor called.
B'default constructor called.
A'default constructor called.
A'default constructor called.
B'default constructor called.
A' constructor called. // 匿名對(duì)象的構(gòu)造
A' constructor called.
B' constructor called.
A'destructor called. // 匿名對(duì)象的析構(gòu)
A'destructor called.
B'destructor called.
A' constructor called. // 匿名對(duì)象的構(gòu)造
A' constructor called.
B' constructor called.
A'destructor called. // 匿名對(duì)象的析構(gòu)
A'destructor called.
B'destructor called.
1 , 5 , 2
3 , 7 , 4
B'destructor called.
A'destructor called.
A'destructor called.
B'destructor called.
A'destructor called.
A'destructor called.
2、析構(gòu)函數(shù):當(dāng)對(duì)象被刪除時(shí),派生類的析構(gòu)函數(shù)被執(zhí)行。由于析構(gòu)函數(shù)也不能被繼承,因此在執(zhí)行派生類的析構(gòu)函數(shù)時(shí),基類的析構(gòu)函數(shù)也將被調(diào)用。執(zhí)行順序是先執(zhí)行派生類的析構(gòu)函數(shù),再執(zhí)行基類的析構(gòu)函數(shù),其執(zhí)行順序與執(zhí)行構(gòu)造函數(shù)時(shí)的順序相反。
例如:分析下列程序的輸出結(jié)果:
#include
class M
{
public:
M(){m1=m2=0;}
M(int I,int j){m1=I;m2=j;}
Void Print(){cout<
~M(){cout<<”M's destructor called.\n”;}
private:
int m1,m2;
}
class N: public M
{
public:
N(){n=0;}
N(int I,int j,int k);
Void Print()
{
M::Print();
Cout<
~N(){cout<<”N's Destructor called.\n”;}
private:
int n;
};
N::N(int I,int j,int k):M(I,j),n(k)
{}
void main()
{
N n1(5,6,7),n2(-2,-3,-4);
n1.Print();
n2.Print();
}
運(yùn)行結(jié)果: 5,6,7
-2,-3,-4
N's destructor called.
M's destructor called.
N's destructor called.
M's destructor called.
3、 派生類構(gòu)造函數(shù)使用中應(yīng)注意的問題:
• 派生類構(gòu)造函數(shù)的定義中可以省略對(duì)其基類構(gòu)造函數(shù)的調(diào)用,其條件是在基類中必須有缺省的構(gòu)造函數(shù),或者根本沒有定義構(gòu)造函數(shù)。
例如:分析下列程序的輸出結(jié)果:
#include
class A
{
public:
A(){a=0;}
Void print() {cout<
private:
int a;
};
class B:public A
{
public:
B(){b1=b2=0;}
B(int I){b1=I;b2=0;}
B(int I,int j,int k):A(i),b1(j),b2(k){}
Void print()
{A::print();
cout<
}
private:
int b1,b2;
};
void main()
{
B d1;
B d2(5);
B d3(4,5,6);
d1.print();
d2.print();
d3.print();
}
結(jié)果: 0,0,0
0,5,0
4,5,6
• 當(dāng)基類的構(gòu)造函數(shù)使用一個(gè)或多個(gè)參數(shù)時(shí),則派生類必須定義構(gòu)造函數(shù),提供將參數(shù)傳遞給基類構(gòu)造函數(shù)的途徑。在有的情況下,派生類構(gòu)造函數(shù)的函數(shù)體可能為空,僅起到參數(shù)傳遞的作用。
Class B
{
public:
B(int I,int j){b1=I;b2=j;}
Privte:
Int b1,b2;
};
class D:public B
{
public:
D(int I,int j,int k,int l,int m);
Private:
Int d1;
B bb;
};
D::D(int I,int j,int k,int l,int m):B(I,j),bb(k,l)
{d1=m;}
分析:派生類的 構(gòu)造函數(shù)有 5 個(gè)參數(shù),其中前兩個(gè)參數(shù)傳遞給基類 B 的構(gòu)造函數(shù),接著兩個(gè)參數(shù)傳遞給子對(duì)象 bb 的類 B 的構(gòu)造函數(shù),最后一個(gè)參數(shù)是傳遞給派生類 D 的數(shù)據(jù)成員 d1 。

