当前位置:网站首页>派生類的構造函數和析構函數
派生類的構造函數和析構函數
2022-07-22 19:39:00 【wzh_scuec】
派生類的構造和析構函數
派生類的構造函數
在定義派生類時,派生類並沒有把基類的構造函數和析構函數繼承下來。因此,對繼承的基類成員初始化的工作要由派生類的構造函數承擔,同時基類的析構函數也要被派生類的析構函數來調用
1.派生類構造函數的定義
在執行派生類的構造函數時,使派生類的數據成員和基類的數據成員同時都被初始化。其定義形式如下:
派生類名(形式參數列錶):基類名(基類構造函數實參列錶),派生類初始化列錶
{
派生類初始化函數體
}
“基類名(基類構造函數實參列錶)”即是調用基類構造函數,而派生類新增的數據成員可以在“派生類初始化列錶”初始化,也可以在“派生類初始化函數體”中初始化
派生類構造函數的調用順序是:
(1)調用基類構造函數;(2)執行派生類初始化列錶;(3)執行派生類初始化函數體;
例:
class Point {
int x,y;
public:
Point(int a,int b):x(a),y(b) {
} //構造函數
};
class Rect: public Point {
int h,w;
public:
Rect(int a,int b,int c,int d): Point(a,b),h(c),w(d) {
} //派生類構造函數
};
2.組合關系的派生類構造函數
假定派生類A和類B的關系是組合關系,類A中有類B的子對象。如果類B有默認構造函數,或者參數全是默認參數的構造函數,或者有無參數的構造函數,那麼類A的構造函數中可以不用顯式初始化子對象。編譯器總是會自動調用B的構造函數進行初始化
可以在一個類的構造函數中顯式地初始化其子對象,初始化式只能在構造函數初始化列錶中,形式為:
類名(形式參數列錶): 子對象名(子對象構造函數實參列錶),類初始化列錶
{
類初始化函數體
}
調用順序為:
(1)調用基類構造函數;(2)調用子對象構造函數,各個子對象時按其聲明的次序先後調用;(3)執行派生類初始化列錶;(4)執行派生類初始化函數體;
說明:
(1)如果在基類和子對象所屬類的定義中都沒有定義帶參數的構造函數,而且也不需要對派生類自己的數據成員初始化,那麼可以不必顯式地定義派生類構造函數。派生類會合成一個默認構造函數,並在調用派生類構造函數時,會自動先調用基類的默認構造函數和子對象所屬類的默認構造函數
例:
class A {
}; //合成默認構造函數
class B {
}; //合成默認構造函數
class D: public B {
A a; }; //派生類合成默認構造函數
(2)如果在基類中沒有定義構造函數,或定義了沒有參數的構造函數,那麼,在定義派生類構造函數時,可以不顯式地調用基類構造函數。在調用派生類構造函數時,系統會自動先調用基類的無參數構造函數或默認構造函數
例:
class B {
public: B() {
} }; //無參數構造函數
class D: public B {
D() {
} //派生類構造函數不必顯式調用基類構造函數
};
(3)如果在基類或子對象所屬類的定義中定義了帶參數的構造函數,那麼就必須顯式地定義派生類構造函數,並在派生類構造函數中顯式地調用基類或子對象所屬類的構造函數
例:
class A {
public: A(int) {
} }; //有參數構造函數
class B {
public: B(int) {
} }; //有參數構造函數
class D: public B {
D(int x): a(x),B(x) {
} //顯式調用基類或子對象構造函數
A a;
};
(4)如果在基類中既定義了無參數的構造函數,又定義了有參的構造函數(構造函數重載),則在定義派生類構造函數時,既可以顯式調用基類構造函數,也可以不調用基類構造函數
在調用派生類構造函數時,根據構造函數的內容决定調用基類的有參數的構造函數還是無參數的構造函數
可以根據派生類的需要决定采用哪一種方式
派生類的析構函數
在派生時,派生類是不能繼承基類的析構函數的,也需要通過派生類的析構函數去調用基類的析構函數。
派生類中可以根據需要定義自己的析構函數,用來對派生類中所增加的成員進行清理工作。基類的清理工作仍然由基類的析構函數負責
在執行派生類的析構函數時,系統會自動調用基類的析構函數和子對象的析構函數,對基類和子對象進行清理
析構函數調用的順序與構造函數正好相反:先執行派生類自己的析構函數,對派生類新增加的成員進行清理,然後調用子對象的析構函數,對子對象進行清理,最後調用基類的析構函數,對基類進行清理
例:
#include<iostream>
using namespace std;
class A {
public:
A() {
cout<<"A constructor"<<endl;
}
~A() {
cout<<"A destructor"<<endl;
}
};
class B: public A {
public:
B() {
cout<<"B constructor"<<endl;
}
~B() {
cout<<"B destructor"<<endl;
}
};
class C: public B {
public:
C() {
cout<<"C constructor"<<endl;
}
~C() {
cout<<"C destructor"<<endl;
}
};
int main()
{
C text;
return 0;
}
運行結果:
边栏推荐
- PHP Cookie
- Scenario practice | how to use rongyun super group to build a game community
- 国产立体声音频数模D/A转换器DP4344替代兼容CS4344
- 【commons-beanutils专题】004- BeanUtils 专题
- 错过等一年!百度超级链数藏发行服务限时五折
- 7.21 permutation and binary
- Explain the adapter technology in NLP from simple to deep
- Force deduction solution summary 745 prefix and suffix search
- Markdown数学公式语法
- DOM introduction and query
猜你喜欢
Scope and lifecycle of beans
QT中多线程的使用
Methods of wrapping classes and strings
An analysis of the CPU surge of an RFID tag management system in.Net
Batch check crawler
arguments
如何不获取root权限使用第三方主题:MIUI篇
Explain the adapter technology in NLP from simple to deep
国产立体声音频数模D/A转换器DP4344替代兼容CS4344
How many key precautions are there in the process of project implementation?
随机推荐
Force deduction solution summary 1175 prime number arrangement
Don't let fear of marriage kill your happiness!
ATR5179单刀双掷开关芯片替代AS179-92LF
SQL 查询语句性能优化
About human resource outsourcing companies
Delphi提高开发效率之GExperts专家的使用说明
Traversing an array with a pointer
Flutter's first program Hello world!
CV520国产替代CI520非接触式读写器读卡芯片
PHP Cookie
Force deduction solution summary 1217- playing chips
【数据挖掘工程师-笔试】2022年SHEIN 公司
NFT数字藏品系统搭建—app开发
Pytest interface automated testing framework | plug-in secondary development practice
Batch check crawler
有向图的连通性
7.19 binary tree
Force deduction solution summary 745 prefix and suffix search
货币增发为什么会造成通货膨胀? 如何造成
C# 自动生成字典(数据多的时候)