欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中虛表是什么意思(概念及示例)

 更新時(shí)間:2024年03月19日 08:55:45   作者:江水為竭  
虛函數(shù)表,以及虛函數(shù)指針是實(shí)現(xiàn)多態(tài)性(Polymorphism)的關(guān)鍵機(jī)制,這篇文章主要介紹了C++中虛表是什么意思(概念及示例),需要的朋友可以參考下

虛函數(shù)表,以及虛函數(shù)指針是實(shí)現(xiàn)多態(tài)性(Polymorphism)的關(guān)鍵機(jī)制。多態(tài)性允許我們通過(guò)基類的指針或引用來(lái)調(diào)用派生類的函數(shù)

定義

虛函數(shù)(Virtual Function)

  • 定義:類中使用virtual 關(guān)鍵字修飾的函數(shù) 叫做虛函數(shù)

  • 語(yǔ)法

highlighter- cpp

class Base {
public:
    virtual void show() { cout << "Base show" << endl; }
};

虛函數(shù)表(Virtual Function Table)

  • 定義:當(dāng)類含有至少一個(gè)虛函數(shù)時(shí),編譯器會(huì)為該類創(chuàng)建一個(gè)虛函數(shù)表。這個(gè)表是一個(gè)編譯時(shí)構(gòu)建的靜態(tài)數(shù)組,存儲(chǔ)了指向類中所有虛函數(shù)的指針。如果一個(gè)派生類重寫(xiě)了這些函數(shù),那么在派生類的虛表中,相應(yīng)函數(shù)的指針會(huì)被更新為指向派生類中的版本。
  • 作用v-table使得在運(yùn)行時(shí)可以實(shí)現(xiàn)函數(shù)的動(dòng)態(tài)綁定,允許通過(guò)基類的指針或引用調(diào)用正確的函數(shù)版本。

虛函數(shù)指針(Virtual Pointer)

  • 定義:每個(gè)含有虛函數(shù)的類的對(duì)象(實(shí)例化出的)會(huì)持有一個(gè)指向相應(yīng)虛表的指針,這個(gè)指針通常被稱為虛指針(vptr)。vptr是對(duì)象運(yùn)行時(shí)的一部分,確保了當(dāng)通過(guò)基類指針調(diào)用虛函數(shù)時(shí),能夠查找到正確的函數(shù)實(shí)現(xiàn)。
  • 作用:在對(duì)象的生命周期開(kāi)始時(shí),構(gòu)造函數(shù)會(huì)設(shè)置vptr以指向相應(yīng)的虛函數(shù)表。如果有派生類對(duì)象,它的構(gòu)造函數(shù)會(huì)更新vptr,以指向派生類的虛函數(shù)表。這保證了通過(guò)基類的引用或指針調(diào)用虛函數(shù)也會(huì)執(zhí)行最派生類的重寫(xiě)版本。

示例

highlighter- cpp

#include <iostream>
using namespace std;
class Base {
public:
    virtual void func1() { cout << "Base::func1" << endl; }
    virtual void func2() { cout << "Base::func2" << endl; }
};
class Derived : public Base {
public:
    void func1() override { cout << "Derived::func1" << endl; }
    // func2() 繼承自 Base
};
void printVTable(void* obj) {
    cout << "vptr Address: " << obj << endl;
    void** vTable = *(void***)obj;
    cout << "VTable[0] (func1): " << vTable[0] << endl;
    cout << "VTable[1] (func2): " << vTable[1] << endl;
}
int main() {
    Base* base = new Base();
    Derived* derived = new Derived();
    cout << "Base object:" << endl;
    printVTable(base);
    cout << "\nDerived object:" << endl;
    printVTable(derived);
    delete base;
    delete derived;
    return 0;
}

程序輸出如下,可以看到?jīng)]用重寫(xiě)的func2函數(shù)地址是一樣的。

highlighter- apache

Base object:
vptr Address: 0x8c1510   
VTable[0] (func1): 0x422270
VTable[1] (func2): 0x4222b0
Derived object:
vptr Address: 0x8c1530   
VTable[0] (func1): 0x422330
VTable[1] (func2): 0x4222b0

如下圖所示:

面試題

(來(lái)自2024騰訊實(shí)習(xí)面試)場(chǎng)景題:一個(gè)類 A,里面有一個(gè)打印 helloworld 的虛函數(shù),然后類 A 會(huì)在構(gòu)造函數(shù)里調(diào)用這個(gè)虛函數(shù),此時(shí)有個(gè)類 B,繼承A,重寫(xiě)了這個(gè) helloworld虛函數(shù),問(wèn)你在創(chuàng)建類 B 時(shí),會(huì)打印 A 里的 helloworld 還是 B 里的。

代碼如下:

highlighter- arduino

class A {
public:
    A() {
        print();
    }
    virtual void print() {
        cout << "A print" << endl;
    }
};
class B : public A {
public:
    void print() override {
        cout << "B print" << endl;
    }
};
int main() {
    A* aTemp = new B();
    delete aTemp;
}

解答:基類構(gòu)造函數(shù)執(zhí)行的時(shí)候,派生類的部分尚未初始化,因此調(diào)用的虛函數(shù)不會(huì)下發(fā)到派生類中。

最終會(huì)打印 A print,而不是類 B 里重寫(xiě)的版本

到此這篇關(guān)于C++中虛表是什么的文章就介紹到這了,更多相關(guān)C++虛表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)LeetCode(2.兩個(gè)數(shù)字相加)

    C++實(shí)現(xiàn)LeetCode(2.兩個(gè)數(shù)字相加)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(兩個(gè)數(shù)字相加),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實(shí)現(xiàn)LeetCode(22.生成括號(hào))

    C++實(shí)現(xiàn)LeetCode(22.生成括號(hào))

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(22.生成括號(hào)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++設(shè)計(jì)模式之狀態(tài)模式

    C++設(shè)計(jì)模式之狀態(tài)模式

    這篇文章主要介紹了C++設(shè)計(jì)模式之狀態(tài)模式,本文講解了什么是狀態(tài)模式、狀態(tài)模式的使用場(chǎng)合、狀態(tài)模式的實(shí)現(xiàn)代碼等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • 深入理解C/C++混合編程

    深入理解C/C++混合編程

    本篇文章是對(duì)C/C++混合編程進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 簡(jiǎn)要介紹C++編程中的友元函數(shù)和友元類

    簡(jiǎn)要介紹C++編程中的友元函數(shù)和友元類

    這篇文章主要介紹了C++編程中的友元函數(shù)和友元類,屬于較為冷僻的知識(shí),在實(shí)際開(kāi)發(fā)中較少使用,需要的朋友可以參考下
    2015-09-09
  • Linux管道揭秘之匿名管道連接進(jìn)程世界的方法

    Linux管道揭秘之匿名管道連接進(jìn)程世界的方法

    文章介紹了Linux中的管道(Pipe)概念,包括其定義、作用、類型、工作原理以及如何在父子進(jìn)程間使用,匿名管道是進(jìn)程間通信的一種機(jī)制,通過(guò)pipe()系統(tǒng)調(diào)用創(chuàng)建,具有讀端和寫(xiě)端文件描述符,文章詳細(xì)解釋了匿名管道的創(chuàng)建、使用流程、4種情況和5種特性
    2024-11-11
  • C++示例講解string容器

    C++示例講解string容器

    c++相比c的一個(gè)好處就是實(shí)現(xiàn)了很多的容器和泛型算法,使得程序員的工作得到了很大的簡(jiǎn)化,本文重點(diǎn)給大家介紹C++string容器基本概念講解,需要的朋友參考下吧
    2022-07-07
  • C++基于字符串實(shí)現(xiàn)大數(shù)相乘問(wèn)題的代碼詳解

    C++基于字符串實(shí)現(xiàn)大數(shù)相乘問(wèn)題的代碼詳解

    在實(shí)際編程中,我們經(jīng)常會(huì)遇到需要處理大整數(shù)的情況,由于編程語(yǔ)言中內(nèi)置整數(shù)類型有其表示范圍的限制,當(dāng)需要處理的整數(shù)超出這些范圍時(shí),就不能直接使用內(nèi)置類型進(jìn)行計(jì)算,所以本文給大家介紹了相關(guān)的解決方法,需要的朋友可以參考下
    2025-03-03
  • 更優(yōu)雅的C++字符串格式化實(shí)現(xiàn)方法詳解

    更優(yōu)雅的C++字符串格式化實(shí)現(xiàn)方法詳解

    在用C++編寫(xiě)代碼時(shí),經(jīng)常需要用到字符串拼接及格式化,尤其是在拼寫(xiě)sql語(yǔ)句時(shí)。所以本文為大家介紹了更優(yōu)雅的C++字符串格式化實(shí)現(xiàn)方法,希望對(duì)大家有所幫助
    2023-04-04
  • C++ OpenCV實(shí)戰(zhàn)之文檔照片轉(zhuǎn)換成掃描文件

    C++ OpenCV實(shí)戰(zhàn)之文檔照片轉(zhuǎn)換成掃描文件

    這篇文章主要為大家介紹一個(gè)C++?OpenCV的實(shí)戰(zhàn)——文檔照片轉(zhuǎn)換成掃描文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-09-09

最新評(píng)論