激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - 一文讀懂C++ 虛函數(shù) virtual

一文讀懂C++ 虛函數(shù) virtual

2021-10-28 14:39YJY-Simon C/C++

這篇文章主要介紹了C++ 虛函數(shù) virtual的相關(guān)資料,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

探討 C++ 虛函數(shù) virtual

有無虛函數(shù)的對比

C++ 中的虛函數(shù)用于解決動態(tài)多態(tài)問題,虛函數(shù)的作用是允許在派生類中重新定義與積累同名的函數(shù),并且可以通過基類指針或引用來訪問基類和派生類中的同名函數(shù)。

首先寫兩個簡單的類,類 B 繼承自類 A,即 A 是基類,B 是派生類。

class A{
public:
  void print(){
    cout << "A" << endl;
  }
};

class B : public A {
public:
  void print(){
    cout << "B" << endl;
  }
};

int main()
{
  B b;		//創(chuàng)建一個 B 類對象 b;
  A &a = b;	//a 是 b 的一個 A 類引用;
  A *pa = &b; //pa 是一個指向 A 類對象的指針;
  a.print();
  pa->print();
  b.print();
  return 0;
}

程序中,A 類和 B 類均定義了一個同名函數(shù) print ,但兩個函數(shù)的功能不同,編譯系統(tǒng)按照同名覆蓋原則決定調(diào)用對象。

另外一點,引用的本質(zhì)是指針常量,可以認(rèn)為 a,pa 都指向了 b。( 注意區(qū)分常量指針指針常量,常量指針可以類比于整型指針,即指向一個常量的指針,指針的指向可以修改;指針常量類比于整型常量,即一個指針是個常量,也就是指針只能固定的指向某一單元,指針常量的指向不可改而指向的值可以修改。)

int a, b;
int * const p1 = &a; //指針常量
const int *p2 = &b; //常量指針

執(zhí)行函數(shù)后,我們發(fā)現(xiàn)結(jié)果為

一文讀懂C++ 虛函數(shù) virtual

因為 a 是 A 類的一個引用,所以 a 的 print( ) 依舊是 A 類的成員函數(shù);pa 是 A 類的指針,同理;而 b 是 B 類的對象,調(diào)用的 print( ) 為 B 類的成員函數(shù)。簡言之就是,沒有 virtual 時,調(diào)用哪一類的成員函數(shù)取決于調(diào)用對象 a ,pa,b 在定義時的類型。而此時,若 B 類對象 b 想調(diào)用直接基類 A 的 print 函數(shù),則應(yīng)當(dāng) b.A::print( )

這種 a,pa,b 能調(diào)用哪個同名函數(shù)在對象定義時已經(jīng)確定好了的多態(tài),我們稱之為靜態(tài)多態(tài)。什么是多態(tài)?同一個 print 函數(shù)在不同的對象中有不同的作用,這就呈現(xiàn)了多態(tài)。

這里再提一點,原本基類指針是用來指向基類對象的,如果用它指向派生類對象,此時基類指針指向的是派生類對象中的基類部分。在沒有虛函數(shù)時,基類指針是無法調(diào)用派生類對象中的成員函數(shù)的。

而當(dāng)我們在 A 類中 print( ) 前加上關(guān)鍵字 virtual,變成虛函數(shù)時

class A{
public:
  virtual void print(){
    cout << "A" << endl;
  }
};

class B : public A{
public:
  void print(){
    cout << "B" << endl;
  }
};

再次執(zhí)行主函數(shù),結(jié)果為

一文讀懂C++ 虛函數(shù) virtual

這是因為 virtual 跟著對象走,即調(diào)用的 print( ) 究竟是 A 類還是 B 類的成員函數(shù)取決于“ 調(diào)用者 ” a,pa 所指的對象 b 屬于哪一類,而不再是取決于 a,pa 本身在定義時的類型了。

這種用基類指針或引用指向某一派生類對象,從而能夠調(diào)用指針指向的派生類對象中的函數(shù)的多態(tài),我們稱為動態(tài)多態(tài),virtual 正是實現(xiàn)動態(tài)多態(tài)的關(guān)鍵字。

虛函數(shù)表

接著剛才的話題,在 A 類中有虛函數(shù)的前提下,我們繼續(xù)討論

class C{
public:
  void print(){
    cout << "C" << endl;
  }
};

int main()
{
  cout << "sizeof(A): " << sizeof(A) << endl;
  cout << "sizeof(B): " << sizeof(B) << endl;
  cout << "sizeof(C): " << sizeof(C) << endl;
  A a;
  B b;
  C c;
  cout << "sizeof(a): " << sizeof(a) << endl;
  cout << "sizeof(b): " << sizeof(b) << endl;
  cout << "sizeof(c): " << sizeof(c) << endl;
  return 0;
}

執(zhí)行結(jié)果為

一文讀懂C++ 虛函數(shù) virtual

為什么有虛函數(shù)的 A 類大小為 8 字節(jié),繼承 A 的 B 為 8 字節(jié),而沒有虛函數(shù)的 C 類是 1 字節(jié)呢?聯(lián)想到 64 位操作系統(tǒng)下指針占8個字節(jié)內(nèi)存,而 A 大小也是 8 字節(jié),是巧合嗎?事實上,在包含虛函數(shù)的類中,在該類的存儲空間中,會有一個指向虛函數(shù)表的指針,正是這個指針使 A 的大小變?yōu)?8 字節(jié)。而指針?biāo)傅奶摵瘮?shù)表本質(zhì)上是 A 類中定義的所有虛函數(shù)名構(gòu)成的列表。A 中只定義了一個虛函數(shù) print( ) ,所以虛函數(shù)表中也只有一個虛函數(shù)名 print,通過這個虛函數(shù)名,再找到整個虛函數(shù) print( ) 在內(nèi)存中的存儲位置 ( B 同理 ) 。

驗證虛函數(shù)表的存在性

虛函數(shù)表看不見摸不著,怎么確定它的存在呢?

int main()
{
  A a;
  B b;
  a.print();
  b.print();
  cout << "-------------------" << endl;
  typedef void (*func)();		//利用函數(shù)指針 func;
  ((func**)(&a))[0][0]();		//((func**)(&a))[0] 代表對象 a 的內(nèi)存空間中的第一個元素:指向虛函數(shù)表的指針;
  ((func**)(&b))[0][0](); 	//((func**)(&a))[0][0] 表示虛函數(shù)表中第一個函數(shù)名;
  return 0;
}

一文讀懂C++ 虛函數(shù) virtual

從結(jié)果中我們可以發(fā)現(xiàn),((func**)(&a))[0][0](); 等效于 a.print();,即確實證明了對象 a 的內(nèi)存空間中存有一個指向虛函數(shù)表的指針,虛函數(shù)表的第一個函數(shù)名正是 print 。

到此這篇關(guān)于一文讀懂C++ 虛函數(shù) virtual的文章就介紹到這了,更多相關(guān)C++ 虛函數(shù) virtual內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://blog.csdn.net/weixin_44636463/article/details/114336411

延伸 · 閱讀

精彩推薦
  • C/C++學(xué)習(xí)C++編程的必備軟件

    學(xué)習(xí)C++編程的必備軟件

    本文給大家分享的是作者在學(xué)習(xí)使用C++進(jìn)行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++深入理解goto語句的替代實現(xiàn)方式分析

    深入理解goto語句的替代實現(xiàn)方式分析

    本篇文章是對goto語句的替代實現(xiàn)方式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下...

    C語言教程網(wǎng)7342020-12-03
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    strcpy 和strcnpy函數(shù)是字符串復(fù)制函數(shù)。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數(shù)使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當(dāng)程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關(guān)于C語言中文件...

    針眼_6702022-01-24
  • C/C++C/C++經(jīng)典實例之模擬計算器示例代碼

    C/C++經(jīng)典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典實例之模擬計算器的相關(guān)資料,文中通過示...

    jia150610152021-06-07
  • C/C++C語言實現(xiàn)電腦關(guān)機(jī)程序

    C語言實現(xiàn)電腦關(guān)機(jī)程序

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)電腦關(guān)機(jī)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    這篇文章主要介紹了c++ 單線程實現(xiàn)同時監(jiān)聽多個端口的方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
主站蜘蛛池模板: 久久av喷吹av高潮av懂色 | 精品久久久久久久久中文字幕 | 曰韩毛片 | 成人性生活视频 | 欧美在线另类 | av色先锋 | 国产免费视频一区二区裸体 | 日韩黄在线观看 | 港台三级在线观看 | 手机av免费电影 | 久久久久久久国产视频 | 国产91大片 | 国产人妖一区二区 | 中文字幕精品亚洲 | 欧美精品一区二区免费 | 久章草影院 | 毛片毛片 | 成人精品视频在线 | 久久久一区二区三区精品 | 久久电影一区二区 | 爱福利视频网 | 素人视频在线观看免费 | 欧美日日操 | 性生活视频软件 | julieann艳星激情办公室 | 亚洲免费毛片基地 | 午夜视频在线看 | 国产午夜亚洲精品 | 精品国产一区二区三区久久久狼牙 | 久久国产不卡 | 国产毛片网站 | 香蕉黄色网| 国产麻豆久久 | 国产在线精品一区二区夜色 | 欧美精品日日鲁夜夜添 | 92精品国产自产在线 | 成人一级毛片 | 亚洲免费视频大全 | 成人福利视频导航 | 欧美第1页 | 成人欧美视频 |