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

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

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

1.為什么需要virtual

按照J(rèn)ava的思維方式,在有了繼承和向上類型轉(zhuǎn)換(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關(guān)鍵字,將上面代碼里的class A修改如下,main中的輸出就變成類B中f()的輸出了。

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

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

有兩點需要注意的:

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

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

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

一般情況下,在基類中我們不會對純虛函數(shù)進(jìn)行實現(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.構(gòu)造函數(shù)與虛函數(shù)

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

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

構(gòu)造函數(shù)不能被定義為虛函數(shù),而析構(gòu)函數(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)性時,不把析構(gòu)函數(shù)定義成虛函數(shù)所帶來的影響。這種錯誤不會立刻使程序崩潰,但是它不知不覺中使內(nèi)存泄漏。

5.純虛析構(gòu)函數(shù)的應(yīng)用

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

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

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

還要注意一點,在析構(gòu)函數(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ù)使用原理的詳細(xì)內(nèi)容,更多關(guān)于C++ 多態(tài)性虛函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實現(xiàn)公司人事管理系統(tǒng)

    C++實現(xiàn)公司人事管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)公司人事管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • opencv3/C++基于顏色的目標(biāo)跟蹤方式

    opencv3/C++基于顏色的目標(biāo)跟蹤方式

    今天小編就為大家分享一篇opencv3/C++基于顏色的目標(biāo)跟蹤方式,具有很好的參考價值,希望對的有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • C++中vector操作方式詳解(多種方式)

    C++中vector操作方式詳解(多種方式)

    這篇文章主要介紹了C++中vector操作方式詳解(多種方式),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • c++如何保存vector到文件

    c++如何保存vector到文件

    這篇文章主要介紹了c++如何保存vector到文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++實現(xiàn)逆波蘭式

    C++實現(xiàn)逆波蘭式

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)逆波蘭式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • OpenGL繪制貝塞爾曲線

    OpenGL繪制貝塞爾曲線

    這篇文章主要為大家詳細(xì)介紹了OpenGL繪制貝塞爾曲線,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語言預(yù)編譯#define(預(yù)處理)

    C語言預(yù)編譯#define(預(yù)處理)

    這篇文章主要介紹了C語言預(yù)編譯#define(預(yù)處理),#define 機制包括了一個機制,允許把參數(shù)替換到文本中,這種實現(xiàn)通常稱為宏或者宏定義,下文更多的相關(guān)資料介紹需要的小伙伴可以參考一下
    2022-04-04
  • C語言使用mciSendString實現(xiàn)播放音樂功能

    C語言使用mciSendString實現(xiàn)播放音樂功能

    mciSendString?支持?mp3、wma、wav、mid?等多種媒體格式,使用非常簡單。這篇文章就來為大家介紹一下C語言如何使用mciSendString實現(xiàn)播放音樂功能,需要的可以參考一下
    2023-02-02
  • Qt?TCP網(wǎng)絡(luò)通信學(xué)習(xí)

    Qt?TCP網(wǎng)絡(luò)通信學(xué)習(xí)

    用于數(shù)據(jù)傳輸?shù)牡蛯泳W(wǎng)絡(luò)協(xié)議,多個物聯(lián)網(wǎng)協(xié)議都是基于TCP協(xié)議的,這篇文章為大家介紹了Qt?TCP網(wǎng)絡(luò)通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Ubuntu 20.04 下安裝配置 VScode 的 C/C++ 開發(fā)環(huán)境(圖文教程)

    Ubuntu 20.04 下安裝配置 VScode 的 C/C++ 開發(fā)環(huán)境(圖文教程)

    這篇文章主要介紹了Ubuntu 20.04 下安裝配置 VScode 的 C/C++ 開發(fā)環(huán)境,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05

最新評論