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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

c++面向对象高级编程 学习十六 vptr和vtbl

發布時間:2023/12/13 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++面向对象高级编程 学习十六 vptr和vtbl 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

當一個類中有一個或多個虛函數時,內存中會多一個虛指針(vptr,virtual pointer),指向一個虛表(vtbl,virtual table)

父類有虛函數,則子類一定有虛函數

在下圖示意圖中,我們可知,B繼承A,C繼承B。
A有兩個虛函數,B繼承A則也有兩個虛函數,同時B對虛函數vfunc1進行了重寫,同理,C繼承B,則C也有兩個虛函數,C對虛函數vfunc1也進行了重寫。故在內存中,A B C對應的虛函數vfunc2是同一個均為A::vfunc2,對應的虛函數vfunc1分別為A::vfunc1,B::vfunc1,C::vfunc1。


c++編譯器遇到函數調用時,會有兩個考量,是靜態綁定還是動態綁定,靜態綁定是call xxx地址,即一定調用到某個地址,動態綁定可以調用到不同的地址

動態綁定需符合三個條件:

  • 通過指針調用(對象調用函數是靜態綁定
  • 指針是向上的關系,向上關系是指,比如 父類 名稱 = new 子類(),這樣的關系即是一種向上的關系
  • 調用的是虛函數

虛函數的這種用法,稱之為多態

示例程序:

#include<iostream> using namespace std;class A { public:A(int data1, int data2) :m_data1(data1), m_data2(data2) {}virtual void vfunc1() { cout << "調用的是A的vfunc1"<< endl; }virtual void vfunc2() { cout << "調用的是A的vfunc2" << endl; }void func1() { cout << "調用的是A的func1" << endl; }void func2() { cout << "調用的是A的func2" << endl; }void getData() {cout << "A的m_data1:" << m_data1 << ",A的m_data2:" << m_data2 << endl;} private:int m_data1, m_data2; };class B:public A { public:B(int n1,int n2,int n3) :A(n1,n2), m_data3(n3){}virtual void vfunc1() { cout << "調用的是B的vfunc1" << endl; }void func2() { cout << "調用的是B的func2" << endl; }void getData() {A::getData();cout << "B的m_data3:" << m_data3 << endl;} private:int m_data3; };class C :public B { public:C(int n1, int n2, int n3,int n4,int n5):B(n1,n2,n3) , m_data1(n4), m_data4(n5) {}virtual void vfunc1() { cout << "調用的是C的vfunc1" << endl; }void func2() { cout << "調用的是C的func2" << endl; }void getData() {B::getData();cout << "C的m_data1:" << m_data1 << ",C的m_data4:" << m_data4 << endl;} private:int m_data1, m_data4; };

測試程序:

int main() {A a(1,2);a.vfunc1();a.vfunc2();a.func1();a.func2();a.getData();cout << endl;B b(3,4,5);b.vfunc1();b.vfunc2();b.func1();b.func2();b.getData();cout << endl;C c(6,7,8,9,10);c.vfunc1();c.vfunc2();c.func1();c.func2();c.getData();cout << endl;A* d = new B(1,3,5);d->vfunc1();d->vfunc2();d->func1();d->func2();d->getData();cout << endl;A* d2 = new C(1, 3, 5,7,9);d2->vfunc1();d2->vfunc2();d2->func1();d2->func2();d2->getData();system("pause");return 0; }

輸出結果:

調用的是A的vfunc1 調用的是A的vfunc2 調用的是A的func1 調用的是A的func2 A的m_data1:1,A的m_data2:2調用的是B的vfunc1 調用的是A的vfunc2 調用的是A的func1 調用的是B的func2 A的m_data1:3,A的m_data2:4 B的m_data3:5調用的是C的vfunc1 調用的是A的vfunc2 調用的是A的func1 調用的是C的func2 A的m_data1:6,A的m_data2:7 B的m_data3:8 C的m_data1:9,C的m_data4:10調用的是B的vfunc1 調用的是A的vfunc2 調用的是A的func1 調用的是A的func2 A的m_data1:1,A的m_data2:3調用的是C的vfunc1 調用的是A的vfunc2 調用的是A的func1 調用的是A的func2 A的m_data1:1,A的m_data2:3

從輸出結果中,我們可以看出,當對函數進行重寫后,子類在調用函數時會調用重寫后的函數。當函數是虛函數時,若我們按照父類 名稱 = new 子類() 的形式生成指針,則該指針在調用函數時,若調用的函數是虛函數,則其會調用子類重寫后的虛函數,若調用的函數不是虛函數,則無論子類對該函數是否重寫,調用的均為父類的函數。

總結

以上是生活随笔為你收集整理的c++面向对象高级编程 学习十六 vptr和vtbl的全部內容,希望文章能夠幫你解決所遇到的問題。

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