日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++基础16-类和对象之联编,重写,虚析构

發(fā)布時(shí)間:2025/3/15 c/c++ 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++基础16-类和对象之联编,重写,虚析构 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1、靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編

1、聯(lián)編是指一個(gè)程序模塊、代碼之間互相關(guān)聯(lián)的過程。

2、靜態(tài)聯(lián)編(sta5c binding),是程序的匹配、連接在編譯階段實(shí)現(xiàn),也稱為早期匹配。重載函數(shù)使用靜態(tài)聯(lián)編。

3、動(dòng)態(tài)聯(lián)編是指程序聯(lián)編推遲到運(yùn)行時(shí)進(jìn)行,所以又稱為晚期聯(lián)編(遲綁定)。switch 語句 if 語句多態(tài)是動(dòng)態(tài)聯(lián)編的例子。

說明:

1C++C相同,是靜態(tài)編譯型語言

2、在編譯時(shí),編譯器自動(dòng)根據(jù)指針的類型判斷指向的是一個(gè)什么樣的對(duì)象;所以編譯器認(rèn)為父類指針指向的是父類對(duì)象。

3、由于程序沒有運(yùn)行,所以不可能知道父類指針指向的具體是父類對(duì)象還是子類對(duì)象從程序安全的角度,編譯器假設(shè)父類指針只指向父類對(duì)象,因此編 譯的結(jié)果為調(diào)用父類的成員函數(shù)。這種特性就是靜態(tài)聯(lián)編。

4、多態(tài)的發(fā)生是動(dòng)態(tài)聯(lián)編,實(shí)在程序執(zhí)行的時(shí)候判斷具體父類指針應(yīng)該調(diào)用的方法。

//A.動(dòng)態(tài)聯(lián)編的基礎(chǔ)是虛函數(shù)
//B.動(dòng)態(tài)聯(lián)編時(shí)在運(yùn)行時(shí)確定所調(diào)用的函數(shù)代碼
//C.只有通過基類的指針或引用才能實(shí)現(xiàn)動(dòng)態(tài)聯(lián)編

2、虛析構(gòu)函數(shù)

構(gòu)造函數(shù)不能是虛函數(shù)。建立一個(gè)派生類對(duì)象時(shí),必須從類層次的根開始,沿著繼承路徑逐個(gè)調(diào)用基類的構(gòu)造函數(shù)。

析構(gòu)函數(shù)可以是虛的虛析構(gòu)函數(shù)用于指引 delete 運(yùn)算符正確析構(gòu)動(dòng)態(tài) 對(duì)象

??? 通常用于父類指針指向子類對(duì)象時(shí),釋放父類指針時(shí)會(huì)默認(rèn)調(diào)用父類析構(gòu)函數(shù),而不會(huì)調(diào)用子類的析構(gòu)函數(shù),可能會(huì)造成內(nèi)存泄漏。當(dāng)把父類的析構(gòu)函數(shù)定義為虛函數(shù)時(shí),當(dāng)釋放父類指針時(shí)就會(huì)發(fā)生多態(tài),先調(diào)用子類析構(gòu)函數(shù),再調(diào)用父類構(gòu)造函數(shù)

3、重載、重寫、重定義

重載(添加):

???????? a 相同的范圍(在同一個(gè)類中)

???????? b 函數(shù)名字相同

???????? c 參數(shù)不同 (個(gè)數(shù)或類型)

???????? d virtual關(guān)鍵字可有可無

重寫(覆蓋) 是指派生類函數(shù)覆蓋基類函數(shù),特征是:

??????? a 不同的范圍,分別位于基類和派生類中

??????? b 函數(shù)的名字相同

??????? c 參數(shù)相同

??????? d 基類函數(shù)必須有virtual關(guān)鍵字

重定義(隱藏) 是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù),規(guī)則如下:

?????? a 如果派生類的函數(shù)和基類的函數(shù)同名,但是參數(shù)不同,此時(shí),不管有無virtual,基類的函數(shù)被隱藏。

?????? b 如果派生類的函數(shù)與基類的函數(shù)同名,并且參數(shù)也相同,但是基類函數(shù)沒有vitual關(guān)鍵字,此時(shí),基類的函數(shù)被隱藏。

即:重載:同一個(gè)作用域下(形參個(gè)數(shù)不同,類型不同)
?????? 重寫:如果父類是虛函數(shù),子類在定義一遍。則為重寫(虛函數(shù)重寫)
?????? 重定義:發(fā)生在兩個(gè)不同的類中。一個(gè)是父類 一個(gè)是子類。 //父類普通函數(shù),子類重新寫了一遍(普通函數(shù)定義)
????? ?? ? 即:1、普通函數(shù)重定義? 如果父類的普通成員函數(shù),被子類重寫。說是重定義
???????????? ? ?? 2、虛函數(shù)重寫 如果父類的虛函數(shù),被子類重寫,就是虛函數(shù)重寫。這個(gè)函數(shù)會(huì)發(fā)生多態(tài)

虛析構(gòu)函數(shù)代碼示例:
?

#if 1 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; #if 0 class A { public:A() {cout << "A() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "A String...");}virtual void print() {cout << "A的print函數(shù)" << this->p << endl;}~A() {cout << "~A()" << endl;if (this->p != NULL) {delete this->p;this->p = NULL;}} private:char *p; }; class B :public A { public:B() { //會(huì)觸發(fā)A的構(gòu)造函數(shù)cout << "B() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "B String...");}virtual void print() {cout << "B的print函數(shù)" << this->p << endl;}~B() {cout << "~B()" << endl;if (this->p != NULL) { //默認(rèn)是B的pdelete this->p;this->p = NULL;}} private:char* p; }; void func(A *p) {p->print(); } void test01() {A a; func(&a);cout << "------" << endl;B b;func(&b); } /* A() A的print函數(shù)A String... ------ A() B() B的print函數(shù)B String... ~B() ~A() ~A() */ void test02() {B *bp = new B;func(bp);delete bp; } /* A() B() B的print函數(shù)B String... ~B() ~A() */ void func2(A *p) {p->print(); //發(fā)生多態(tài)delete p; //也應(yīng)該發(fā)生多態(tài)//此刻觸發(fā)p默認(rèn)的析構(gòu)函數(shù)//應(yīng)該是觸發(fā)誰 調(diào)用誰的析構(gòu)函數(shù) 多態(tài) } void test03() {A *ap = new A;func2(ap); } /* A() A的print函數(shù)A String... */ void test04() {B *bp = new B;func2(bp); } /* A() B() B的print函數(shù)B String... ~A() */ #endif //在上面的基礎(chǔ)上,將A的析構(gòu)函數(shù)改為虛函數(shù) class A { public:A() {cout << "A() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "A String...");}virtual void print() {cout << "A的print函數(shù)" << this->p << endl;}virtual ~A() {cout << "~A()" << endl;if (this->p != NULL) {delete this->p;this->p = NULL;}} private:char *p; }; class B :public A { public:B() { //會(huì)觸發(fā)A的構(gòu)造函數(shù)cout << "B() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "B String...");}virtual void print() {cout << "B的print函數(shù)" << this->p << endl;}virtual ~B() {cout << "~B()" << endl;if (this->p != NULL) { //默認(rèn)是B的pdelete this->p;this->p = NULL;}} private:char* p; }; void func2(A *p) {p->print();delete p; //此刻觸發(fā)p默認(rèn)的析構(gòu)函數(shù)//應(yīng)該是觸發(fā)誰 調(diào)用誰的析構(gòu)函數(shù) 多態(tài) } void test05() {B *bp = new B;func2(bp); } /* A() B() B的print函數(shù)B String... ~B() ~A() */ int main() {//test01();//test02();//test03();//test04();test05();return 0; }//重載:同一個(gè)作用域下(形參個(gè)數(shù)不同,類型不同) //重寫:如果父類是虛函數(shù),子類在定義一遍。則為重寫(虛函數(shù)重寫) //重定義:發(fā)生在兩個(gè)不同的類中。一個(gè)是父類 一個(gè)是子類。//父類普通函數(shù),子類重新寫了一遍(普通函數(shù)定義) //即:1、普通函數(shù)重定義 如果父類的普通成員函數(shù),被子類重寫。說是重定義 // 2、虛函數(shù)重寫 如果父類的虛函數(shù),被子類重寫,就是虛函數(shù)重寫。這個(gè)函數(shù)會(huì)發(fā)生多態(tài)//A.動(dòng)態(tài)聯(lián)編的基礎(chǔ)是虛函數(shù) //B.動(dòng)態(tài)聯(lián)編時(shí)在運(yùn)行時(shí)確定所調(diào)用的函數(shù)代碼 //C.只有通過基類的指針或引用才能實(shí)現(xiàn)動(dòng)態(tài)聯(lián)編 #endif

?

總結(jié)

以上是生活随笔為你收集整理的C++基础16-类和对象之联编,重写,虚析构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。