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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++多态的基本语法与原理剖析

發布時間:2023/12/4 c/c++ 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++多态的基本语法与原理剖析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多態分為兩類
1.靜態多態:函數重載和運算符重載屬于靜態多態,復用函數名
2.動態多態:派生類和虛函數實現運行時多態

靜態多態和動態多態區別:
1.靜態多態的函數地址早綁定,編譯階段確定函數地址
2.多態多態的函數地址晚綁定,運行階段確定函數地址

首先讓我們看這段代碼:

#include <iostream> using namespace std;class Animal {public:void speak() {cout << "動物在說話" << endl;} };class Cat : public Animal {public:void speak() {cout << "小貓在說話" << endl;} };void dospeak(Animal &animal) {animal.speak();}void test01() {Cat cat;dospeak(cat);}int main() {test01();system("pause");return 0; }

結果為:動物在說話

我們想要的是貓在說話,可最后輸出的結果卻是動物在說話,為什么呢?

因為dospeak函數地址早綁定了,在編譯階段就確定了函數地址

那么我們要怎樣做才能讓貓說話呢?
非常簡單,就是利用動態多態,就是要讓dospeak函數的地址晚綁定(在運行階段進行綁定),我們只要在父類的同名speak函數前面加virtual關鍵字,現在speak函數就變成了虛函數,就解決了上述問題。

代碼如下:

#include <iostream> using namespace std;class Animal {public:virtual void speak() {cout << "動物在說話" << endl;} };class Cat : public Animal {public:void speak() {cout << "小貓在說話" << endl;} };void dospeak(Animal &animal) {animal.speak();}void test01() {Cat cat;dospeak(cat);}int main() {test01();system("pause");return 0; }

結果為:貓在說話


重寫的概念:
1.函數的返回類型相同
2.函數名相同
3.參數列表相同

動態多態的滿足條件:
1.有繼承關系
2.子類要重寫父類的虛函數

動態多態的使用:
父類的指針或引用指向子類的對象

現在我們來看看多態的原理,首先我們看一下下面這段代碼:

#include <iostream> using namespace std;class Animal {public:void speak() {cout << "動物在說話" << endl;} };class Cat : public Animal {public:void speak() {cout << "小貓在說話" << endl;} };void dospeak(Animal &animal) {animal.speak();}void test01() {cout << "size of Animal = " << sizeof(Animal) << endl;}int main() {test01();system("pause");return 0; }

結果為size of Animal = 1

現在我們在Animal的speak函數前面加上virtual,寫成多態的形式,結果又是多少呢?

#include <iostream> using namespace std;class Animal {public:virtual void speak() {cout << "動物在說話" << endl;} };class Cat : public Animal {public:void speak() {cout << "小貓在說話" << endl;} };void dospeak(Animal &animal) {animal.speak();}void test01() {cout << "size of Animal = " << sizeof(Animal) << endl;}int main() {test01();system("pause");return 0; }

結果為:size of Animal = 4
這說明,加了virtual后,這個類的內部結構發生了改變。
那到底多了什么東西,導致這個類變成了4個字節呢?

結果:
多了指針。
現在讓我們看看這其中發生的變化,
首先我們要知道:
vfptr - 虛函數(表)指針
v - virtual
f - function
ptr - pointer


vftable - 虛函數表
v - virtual
f - function
table - table


現在讓我們看看Animal類內部結構:

Cat內部結構:

當子類重寫父類的虛函數時,子類中的虛函數表內部會替換成子類的虛函數地址
也就是說,當我們往父類Animal的speak函數前面加上virtual時,Cat的內部結構就會變成這樣:


當父類中的指針或者引用指向子類對象的時候,就發生了多態。

我們就相當于寫了這樣一段代碼:
Animal &animal = cat;
animal,speak();
當我們調用animal的speak函數時,由于指向的是Cat對象,所以編譯器會從Cat的虛函數表中找speak函數,就相當于在運行階段發生了多態。

原理:
由于我們寫了一個虛函數,類的內部發生了結構的改變,多了一個虛函數表指針,指向虛函數表,虛函數表內部寫的是虛函數的函數入口地址,當子類重寫了虛函數表,會把自身的虛函數表給替換掉,這里的替換就是Cat類中發生的替換。

總結

以上是生活随笔為你收集整理的C++多态的基本语法与原理剖析的全部內容,希望文章能夠幫你解決所遇到的問題。

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