欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:開發(fā)語言 C++:多態(tài)(繼承)

柚子快報邀請碼778899分享:開發(fā)語言 C++:多態(tài)(繼承)

http://yzkb.51969.com/

hello,各位小伙伴,本篇文章跟大家一起學習《C++:多態(tài)》,感謝大家對我上一篇的支持,如有什么問題,還請多多指教 !

文章目錄

:maple_leaf:多態(tài)的概念:maple_leaf:繼承中的多態(tài)1.:leaves:虛函數(shù)表

:maple_leaf:多態(tài)原理

?多態(tài)的概念

在 C++ 中,多態(tài)性(Polymorphism)是面向?qū)ο缶幊讨幸粋€重要的概念,它允許使用統(tǒng)一的接口來操作不同的對象,從而提高代碼的靈活性、可維護性和可擴展性。多態(tài)性的實現(xiàn)依賴于兩種主要機制:編譯時多態(tài)性(靜態(tài)多態(tài)性)和運行時多態(tài)性(動態(tài)多態(tài)性)。

編譯時多態(tài)性(靜態(tài)多態(tài)性):在 C++ 中,編譯時多態(tài)性主要通過函數(shù)重載和運算符重載來實現(xiàn)。這種多態(tài)性是在編譯期間根據(jù)函數(shù)或運算符的參數(shù)類型和數(shù)量來選擇調(diào)用的函數(shù)版本,稱為靜態(tài)綁定或早期綁定。例如,函數(shù)重載允許在同一個作用域內(nèi)定義多個函數(shù)名相同但參數(shù)列表不同的函數(shù),編譯器會根據(jù)調(diào)用時的參數(shù)類型來選擇正確的函數(shù)。如下實現(xiàn)不同類型進行交換代碼:

void Swap(int& left, int& right)

{

int temp = left;

left = right;

right = temp;

}

void Swap(double& left, double& right)

{

double temp = left;

left = right;

right = temp;

}

void Swap(char& left, char& right)

{

char temp = left;

left = right;

right = temp;

}

運行時多態(tài)性(動態(tài)多態(tài)性):運行時多態(tài)性是通過虛函數(shù)和繼承關(guān)系來實現(xiàn)的。這種多態(tài)性允許在程序運行時根據(jù)對象的實際類型來調(diào)用對應的函數(shù),稱為動態(tài)綁定或后期綁定。在 C++ 中,通過在基類中將成員函數(shù)聲明為虛函數(shù)(使用 virtual 關(guān)鍵字),允許派生類覆蓋(override)這些虛函數(shù)。當通過基類指針或引用調(diào)用虛函數(shù)時,會根據(jù)實際指向的對象類型來決定調(diào)用哪個函數(shù)版本。

下面是一個簡單的示例,展示了 C++ 中的運行時多態(tài)性:

#include

using namespace std;

// Base class

class Animal {

public:

// Virtual function

virtual void speak() {

cout << "Animal speaks!" << endl;

}

};

// Derived class overriding the speak() function

class Dog : public Animal {

public:

// Override the speak() function

void speak() override {

cout << "Dog barks!" << endl;

}

};

// Derived class overriding the speak() function

class Cat : public Animal {

public:

// Override the speak() function

void speak() override {

cout << "Cat meows!" << endl;

}

};

int main() {

Animal *animal;

Dog myDog;

Cat myCat;

// Pointer to Dog object

animal = &myDog;

animal->speak(); // Output: Dog barks!

// Pointer to Cat object

animal = &myCat;

animal->speak(); // Output: Cat meows!

return 0;

}

在這個示例中:

Animal 類中的 speak() 函數(shù)被聲明為虛函數(shù)。Dog 和 Cat 類都重寫了 speak() 函數(shù),實現(xiàn)了不同的動作。在 main() 函數(shù)中,通過 Animal 類指針 animal 分別指向 Dog 對象和 Cat 對象,并調(diào)用它們的 speak() 函數(shù)。雖然指針類型是基類 Animal,但實際上根據(jù)指向的對象類型,調(diào)用的是對應的虛函數(shù)版本,展示了運行時多態(tài)性的特性。

通過多態(tài)性,C++ 提供了一種靈活且強大的機制,使得程序能夠根據(jù)對象的實際類型來決定調(diào)用哪個函數(shù)版本,從而實現(xiàn)代碼的重用性和擴展性。

?繼承中的多態(tài)

1.?虛函數(shù)表

先出一道題,32位機器下,sizeof(Base)答案是多少呢?

class Base

{

public:

virtual void Func1()

{

cout << "Func1()" << endl;

}

private:

int _b = 1;

};

答案是:8 可以看到,除了_b成員,還多一個__vfptr放在對象的前面(注意有些平臺可能會放到對象的最后面,這個跟平臺有關(guān)),對象中的這個指針我們叫做虛函數(shù)表指針(v代表virtual,f代表function)。

class Base

{

public:

virtual void Func1()

{

cout << "Base::Func1()" << endl;

}

virtual void Func2()

{

cout << "Base::Func2()" << endl;

}

void Func3()

{

cout << "Base::Func3()" << endl;

}

private:

int _b = 1;

};

class Derive : public Base

{

public:

virtual void Func1()

{

cout << "Derive::Func1()" << endl;

}

private:

int _d = 2;

};

int main()

{

Base b;

Derive d;

return 0;

}

派生類對象d中也有一個虛表指針,d對象由兩部分構(gòu)成,一部分是父類繼承下來的成員,虛表指針也就是存在部分的另一部分是自己的成員?;恇對象和派生類d對象虛表是不一樣的,這里我們發(fā)現(xiàn)Func1完成了重寫,所以d的虛表中存的是重寫的Derive::Func1,所以虛函數(shù)的重寫也叫作覆蓋,覆蓋就是指虛表中虛函數(shù)的覆蓋。重寫是語法的叫法,覆蓋是原理層的叫法。另外Func2繼承下來后是虛函數(shù),所以放進了虛表,F(xiàn)unc3也繼承下來了,但是不是虛函數(shù),所以不會放進虛表。虛函數(shù)表本質(zhì)是一個存虛函數(shù)指針的指針數(shù)組,一般情況這個數(shù)組最后面放了一個nullptr??偨Y(jié)一下派生類的虛表生成:a.先將基類中的虛表內(nèi)容拷貝一份到派生類虛表中 b.如果派生類重寫了基類中某個虛函數(shù),用派生類自己的虛函數(shù)覆蓋虛表中基類的虛函數(shù) c.派生類自己新增加的虛函數(shù)按其在派生類中的聲明次序增加到派生類虛表的最后。這里還有一個童鞋們很容易混淆的問題:虛函數(shù)存在哪的?虛表存在哪的? 答:虛函數(shù)存在虛表,虛表存在對象中。注意上面的回答的錯的。但是很多童鞋都是這樣深以為然的。注意虛表存的是虛函數(shù)指針,不是虛函數(shù),虛函數(shù)和普通函數(shù)一樣的,都是存在代碼段的,只是他的指針又存到了虛表中。另外對象中存的不是虛表,存的是虛表指針。

?多態(tài)原理

在CS2中,不同槍械的機動性不同:

class Gun

{

public:

virtual void Mobility(Gun& gun) = 0;

};

class AK47 : public Gun

{

public:

void Mobility(Gun& gun)

{

cout << "Mobility = " << _Mobility << endl;

}

private:

int _Mobility = 215;

};

class M4A4 : public Gun

{

public:

void Mobility(Gun& gun)

{

cout << "Mobility = " << _Mobility << endl;

}

private:

int _Mobility = 225;

};

void Func(Gun& gun)

{

gun.Mobility(gun);

}

int main()

{

AK47 ak47;

M4A4 m4a4;

Gun& ak = ak47;

Gun& m4 = m4a4;

Func(ak);

Func(m4);

return 0;

}

多態(tài)必須要滿足兩個條件: 1.必須通過基類的指針或者引用調(diào)用虛函數(shù) 2.被調(diào)用的函數(shù)必須是虛函數(shù),且派生類必須對基類的虛函數(shù)進行重寫

舉個簡單例子解釋,如下代碼:

class Base

{

public:

virtual void Func1()

{

cout << "Base::Func1()" << endl;

}

virtual void Func2()

{

cout << "Base::Func2()" << endl;

}

void Func3()

{

cout << "Base::Func3()" << endl;

}

private:

int _b = 1;

};

class Derive : public Base

{

public:

virtual void Func1()

{

cout << "Derive::Func1()" << endl;

}

private:

int _d = 2;

};

int main()

{

Base b;

Derive d;

Base& s1 = b;

Base& s2 = d;

s1.Func1();

s2.Func1();

return 0;

}

解釋:Derive繼承Base對Func1進行重寫,重寫后的虛函數(shù)會產(chǎn)生新的地址,放入虛表中Base&引用子類Derive對象,會發(fā)生切割,切割部分其實就是繼承Base部分,由于Derive對Func1進行重寫,所以s2虛表中的Func1是已經(jīng)重寫的。

圖解: 你學會了嗎? 好啦,本章對于《C++:多態(tài)(繼承)》的學習就先到這里,如果有什么問題,還請指教指教,希望本篇文章能夠?qū)δ阌兴鶐椭覀兿乱黄姡。。?/p>

如你喜歡,點點贊就是對我的支持,感謝感謝?。。?/p>

柚子快報邀請碼778899分享:開發(fā)語言 C++:多態(tài)(繼承)

http://yzkb.51969.com/

相關(guān)鏈接

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19275460.html

發(fā)布評論

您暫未設置收款碼

請在主題配置——文章設置里上傳

掃描二維碼手機訪問

文章目錄