日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

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

1、靜態聯編和動態聯編

1、聯編是指一個程序模塊、代碼之間互相關聯的過程。

2、靜態聯編(sta5c binding),是程序的匹配、連接在編譯階段實現,也稱為早期匹配。重載函數使用靜態聯編。

3、動態聯編是指程序聯編推遲到運行時進行,所以又稱為晚期聯編(遲綁定)。switch 語句 if 語句多態是動態聯編的例子。

說明:

1C++C相同,是靜態編譯型語言

2、在編譯時,編譯器自動根據指針的類型判斷指向的是一個什么樣的對象;所以編譯器認為父類指針指向的是父類對象。

3、由于程序沒有運行,所以不可能知道父類指針指向的具體是父類對象還是子類對象從程序安全的角度,編譯器假設父類指針只指向父類對象,因此編 譯的結果為調用父類的成員函數。這種特性就是靜態聯編。

4、多態的發生是動態聯編,實在程序執行的時候判斷具體父類指針應該調用的方法。

//A.動態聯編的基礎是虛函數
//B.動態聯編時在運行時確定所調用的函數代碼
//C.只有通過基類的指針或引用才能實現動態聯編

2、虛析構函數

構造函數不能是虛函數。建立一個派生類對象時,必須從類層次的根開始,沿著繼承路徑逐個調用基類的構造函數。

析構函數可以是虛的虛析構函數用于指引 delete 運算符正確析構動態 對象

??? 通常用于父類指針指向子類對象時,釋放父類指針時會默認調用父類析構函數,而不會調用子類的析構函數,可能會造成內存泄漏。當把父類的析構函數定義為虛函數時,當釋放父類指針時就會發生多態,先調用子類析構函數,再調用父類構造函數

3、重載、重寫、重定義

重載(添加):

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

???????? b 函數名字相同

???????? c 參數不同 (個數或類型)

???????? d virtual關鍵字可有可無

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

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

??????? b 函數的名字相同

??????? c 參數相同

??????? d 基類函數必須有virtual關鍵字

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

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

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

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

虛析構函數代碼示例:
?

#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函數" << 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() { //會觸發A的構造函數cout << "B() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "B String...");}virtual void print() {cout << "B的print函數" << this->p << endl;}~B() {cout << "~B()" << endl;if (this->p != NULL) { //默認是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函數A String... ------ A() B() B的print函數B String... ~B() ~A() ~A() */ void test02() {B *bp = new B;func(bp);delete bp; } /* A() B() B的print函數B String... ~B() ~A() */ void func2(A *p) {p->print(); //發生多態delete p; //也應該發生多態//此刻觸發p默認的析構函數//應該是觸發誰 調用誰的析構函數 多態 } void test03() {A *ap = new A;func2(ap); } /* A() A的print函數A String... */ void test04() {B *bp = new B;func2(bp); } /* A() B() B的print函數B String... ~A() */ #endif //在上面的基礎上,將A的析構函數改為虛函數 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函數" << 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() { //會觸發A的構造函數cout << "B() " << endl;this->p = new char[64];//memset(this->p, 0, 64);strcpy(this->p, "B String...");}virtual void print() {cout << "B的print函數" << this->p << endl;}virtual ~B() {cout << "~B()" << endl;if (this->p != NULL) { //默認是B的pdelete this->p;this->p = NULL;}} private:char* p; }; void func2(A *p) {p->print();delete p; //此刻觸發p默認的析構函數//應該是觸發誰 調用誰的析構函數 多態 } void test05() {B *bp = new B;func2(bp); } /* A() B() B的print函數B String... ~B() ~A() */ int main() {//test01();//test02();//test03();//test04();test05();return 0; }//重載:同一個作用域下(形參個數不同,類型不同) //重寫:如果父類是虛函數,子類在定義一遍。則為重寫(虛函數重寫) //重定義:發生在兩個不同的類中。一個是父類 一個是子類。//父類普通函數,子類重新寫了一遍(普通函數定義) //即:1、普通函數重定義 如果父類的普通成員函數,被子類重寫。說是重定義 // 2、虛函數重寫 如果父類的虛函數,被子類重寫,就是虛函數重寫。這個函數會發生多態//A.動態聯編的基礎是虛函數 //B.動態聯編時在運行時確定所調用的函數代碼 //C.只有通過基類的指針或引用才能實現動態聯編 #endif

?

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。