最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解析C++中多態(tài)性和虛函數(shù)使用原理

 更新時間:2023年05月14日 10:47:43   作者:chnmagnus  
這篇文章主要為大家介紹了深入解析C++中多態(tài)性和虛函數(shù)使用原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

1.為什么需要virtual

按照Java的思維方式,在有了繼承和向上類型轉換(upcasting)之后,就可以實現(xiàn)多態(tài)性了。但是在C++中似乎并不能orz??紤]這種情況:

#include<iostream>
using std::cout;
using std::endl;
class A{
public:
  void f() const{
    cout<<"class A's function"<<endl;
  }
};
class B : public A{
public:
  void f() const{
    cout<<"class B's function"<<endl;
  }
};
int main(){
  B b;
  A *ptr_a = &b;
  A &ref_a = b;
  ptr_a->f();//print: class A's function
  ref_a.f();//print: Class A's function
}

在使用基類指針或引用調(diào)用一個派生類對象的函數(shù)時,我們發(fā)現(xiàn)程序仍然在調(diào)用基類的函數(shù),要想解決這種情況,就要引入virtual關鍵字,將上面代碼里的class A修改如下,main中的輸出就變成類B中f()的輸出了。

class A{
public:
  virtual void f() const{
    cout<<"class A's function"<<endl;
  }
};

那么為什么Java不需要呢?因為virtual關鍵字實現(xiàn)功能的同時,會增加該類一些操作的時間和空間占用,C++將這部分占用的優(yōu)化決定權交給了程序員,以實現(xiàn)可能的效率提高;而Java內(nèi)置了virtual的機制,沒有提高效率的選擇,但是簡化了編程。(關于virtual的具體機制,建議參考Thinking in C++)

有兩點需要注意的:

  • 第一、當使用基類指針指向派生類時,無法通過基類指針直接調(diào)用派生類中增加的函數(shù)(基類中沒有同名虛函數(shù)),除非將基類指針強制類型轉換為派生類指針。
  • 第二、只能通過基類指針或者引用來調(diào)用派生類對象,如果我們將一個派生類對象通過值傳遞的方式傳遞給基類對象,這個對象被真的切成一個基類對象,而不具有任何派生類的內(nèi)容。

2.純虛函數(shù)和抽象類

在類設計時,常常希望基類僅僅作為派生類的一個接口,被繼承實現(xiàn),而不會去創(chuàng)建基類對象,這時,可以在基類中定義純虛函數(shù),使其成為一個抽象類。定義純虛函數(shù)語法是在一個虛函數(shù)聲名的基礎上,加上=0。例如:virtual void f() = 0;注意:當繼承一個抽象類時,必須實現(xiàn)其所有的純虛函數(shù),否則繼承出的類也是一個抽象類。

一般情況下,在基類中我們不會對純虛函數(shù)進行實現(xiàn),但是C++提供了實現(xiàn)純虛函數(shù)的機制,這種方法可以讓我們定義一段公共代碼,使派生類可以公用。

class A{
public:
  virtual void do() = 0; 
};
/*
*純虛函數(shù)不能作為inline函數(shù)實現(xiàn),要放在類外!
*/
void A::do(){
  //一些公共代碼
}
class B : public A{
public:
  void do() {
    A::do();
    //其他代碼
  }
};

3.構造函數(shù)與虛函數(shù)

如上文所說,定義一個虛函數(shù)時,需要做一些額外的工作,完成這些工作的代碼其實被秘密插入到類構造函數(shù)的開頭部分。那么就有一個問題,如果我們在構造函數(shù)中調(diào)用虛函數(shù)會發(fā)生什么現(xiàn)象?答案是,會調(diào)用這個虛函數(shù)的本地版本,即虛函數(shù)機制在構造函數(shù)中不工作。
另外,構造函數(shù)也不能被定義為虛函數(shù)。

4.虛析構函數(shù)與純虛析構函數(shù)

構造函數(shù)不能被定義為虛函數(shù),而析構函數(shù)可以,并且經(jīng)常被定義為虛函數(shù)。

#include<iostream>
using namespace std;
class Base1{
public:
  ~Base1(){cout<<"~Base1()"<<endl;}
};
class Base2{
public:
  virtual ~Base2(){cout<<"~Base2()"<<endl;}
};
class Derived1 : public Base1{
public:
  ~Derived1(){cout<<"~Derived1()"<<endl;}
};
class Derived2 : public Base2{
public:
  ~Derived2(){cout<<"~Derived2()"<<endl;}
};
int main(){
  Base1* pd1 = new Derived1();
  Base2* pd2 = new Derived2();
  delete pd1;
  delete pd2;
}

上面代碼的控制臺輸出:

~Base1()
~Derived2()
~Base2()

上面的代碼暴露出在使用多態(tài)性時,不把析構函數(shù)定義成虛函數(shù)所帶來的影響。這種錯誤不會立刻使程序崩潰,但是它不知不覺中使內(nèi)存泄漏。

5.純虛析構函數(shù)的應用

在一些時候,我們需要定義一個抽象類,但是剛好沒有其他純虛函數(shù),這時候我們不妨將析構函數(shù)定義為純虛的,因為作為基類的析構函數(shù)本來就要求為虛函數(shù),將其進一步定義為純虛函數(shù)并無太大不同。唯一需要注意的是,定義純虛析構函數(shù)時必須為其提供函數(shù)體,如下。

class A{
public:
  virtual ~A() = 0;
};
A::~A(){ }

class B:public A{
//不一定需要重定義析構函數(shù),根據(jù)需要
}

還要注意一點,在析構函數(shù)中,虛機制也是不存在的,可通過下面的代碼體會。

#include<iostream>
using namespace std;
class Base{
public:
  virtual ~Base(){cout<<"~Base()"<<endl;f();}
  virtual void f(){cout<<"Base::f()"<<endl;}
};
class Derived : public Base{
public:
  ~Derived(){cout<<"~Derived()"<<endl;}
  void f(){cout<<"Derived::f()"<<endl;}
};
int main(){
  Base * pb = new Derived();
  delete pb;
}

控制臺輸出為:

~Derived()
~Base()
Base::f()

以上就是深入解析C++中多態(tài)性和虛函數(shù)使用原理的詳細內(nèi)容,更多關于C++ 多態(tài)性虛函數(shù)的資料請關注腳本之家其它相關文章!

相關文章

  • C++中stack容器的使用

    C++中stack容器的使用

    本文主要介紹了C++中stack容器的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • C++ Boost MultiIndex使用詳細介紹

    C++ Boost MultiIndex使用詳細介紹

    Boost是為C++語言標準庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標準庫的后備,是C++標準化進程的開發(fā)引擎之一,是為C++語言標準庫提供擴展的一些C++程序庫的總稱
    2022-11-11
  • VSCode無法打開源文件及無法打開鏈接庫文件的解決方法

    VSCode無法打開源文件及無法打開鏈接庫文件的解決方法

    本文主要介紹了VSCode無法打開源文件及無法打開鏈接庫文件的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • C++中左值和右值的區(qū)別詳解

    C++中左值和右值的區(qū)別詳解

    大家好,本篇文章主要講的是C++中左值和右值的區(qū)別詳解,感興趣的同學趕緊來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C語言實現(xiàn)一個簡單的掃雷游戲

    C語言實現(xiàn)一個簡單的掃雷游戲

    掃雷是電腦上很經(jīng)典的游戲,特意去網(wǎng)上玩了一會,幾次調(diào)試之后,發(fā)現(xiàn)這個比三子棋要復雜一些,尤其是空白展開算法上和堵截玩家有的一拼,與實際游戲差別較大,不能使用光標,下面來詳解每一步分析
    2021-10-10
  • C語言數(shù)據(jù)結構堆的基本操作實現(xiàn)

    C語言數(shù)據(jù)結構堆的基本操作實現(xiàn)

    這篇文章主要為大家介紹了C語言數(shù)據(jù)結構堆的基本操作實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2021-11-11
  • 哈夫曼的c語言實現(xiàn)代碼

    哈夫曼的c語言實現(xiàn)代碼

    著先通過 HuffmanTree() 函數(shù)構造哈夫曼樹,然后在主函數(shù) main()中自底向上開始(也就是從數(shù)組序號為零的結點開始)向上層層判斷,若在父結點左側,則置碼為 0,若在右側,則置碼為 1。最后輸出生成的編碼
    2013-07-07
  • C語言操作符基礎知識詳解

    C語言操作符基礎知識詳解

    這篇文章主要以圖文結合的方式為大家詳細介紹了C語言位運算基礎知識,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-10-10
  • c++網(wǎng)絡編程下Linux的epoll技術和Windows下的IOCP模型

    c++網(wǎng)絡編程下Linux的epoll技術和Windows下的IOCP模型

    c++ 網(wǎng)絡編程LINUX-epoll/windows-IOCP下socket opoll函數(shù)用法 優(yōu)于select方法的epoll 以及windows下IOCP 解決多進程服務端創(chuàng)建進程資源浪費問題,感興趣的小伙伴一起來學習吧
    2021-08-08
  • 一篇文章帶你用C語言玩轉結構體

    一篇文章帶你用C語言玩轉結構體

    本文主要介紹C語言 結構體的知識,學習C語言肯定需要學習結構體,這里詳細說明了結構體并附示例代碼,供大家參考學習,有需要的小伙伴可以參考下
    2021-09-09

最新評論

根河市| 连山| 灌云县| 清流县| 青神县| 方山县| 汽车| 鄯善县| 灵川县| 嘉禾县| 合作市| 榆社县| 原平市| 张家口市| 新龙县| 紫阳县| 宕昌县| 类乌齐县| 永兴县| 武安市| 织金县| 太仆寺旗| 密云县| 平阴县| 上栗县| 灵川县| 全南县| 翼城县| 彭州市| 曲水县| 左贡县| 克什克腾旗| 瑞安市| 高平市| 泽库县| 伊川县| 临泉县| 观塘区| 浠水县| 丰县| 米泉市|