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

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

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

1.為什么需要virtual

按照J(rèn)ava的思維方式,在有了繼承和向上類(lèi)型轉(zhuǎn)換(upcasting)之后,就可以實(shí)現(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
}

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

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

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

有兩點(diǎn)需要注意的:

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

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

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

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

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

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

如上文所說(shuō),定義一個(gè)虛函數(shù)時(shí),需要做一些額外的工作,完成這些工作的代碼其實(shí)被秘密插入到類(lèi)構(gòu)造函數(shù)的開(kāi)頭部分。那么就有一個(gè)問(wèn)題,如果我們?cè)跇?gòu)造函數(shù)中調(diào)用虛函數(shù)會(huì)發(fā)生什么現(xiàn)象?答案是,會(huì)調(diào)用這個(gè)虛函數(shù)的本地版本,即虛函數(shù)機(jī)制在構(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;
}

上面代碼的控制臺(tái)輸出:

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

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

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

在一些時(shí)候,我們需要定義一個(gè)抽象類(lèi),但是剛好沒(méi)有其他純虛函數(shù),這時(shí)候我們不妨將析構(gòu)函數(shù)定義為純虛的,因?yàn)樽鳛榛?lèi)的析構(gòu)函數(shù)本來(lái)就要求為虛函數(shù),將其進(jìn)一步定義為純虛函數(shù)并無(wú)太大不同。唯一需要注意的是,定義純虛析構(gòu)函數(shù)時(shí)必須為其提供函數(shù)體,如下。

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

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

還要注意一點(diǎn),在析構(gòu)函數(shù)中,虛機(jī)制也是不存在的,可通過(guò)下面的代碼體會(huì)。

#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;
}

控制臺(tái)輸出為:

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

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

相關(guān)文章

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

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

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

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

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

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

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

    c++如何保存vector到文件

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

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

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

    OpenGL繪制貝塞爾曲線

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

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

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

    C語(yǔ)言使用mciSendString實(shí)現(xiàn)播放音樂(lè)功能

    mciSendString?支持?mp3、wma、wav、mid?等多種媒體格式,使用非常簡(jiǎn)單。這篇文章就來(lái)為大家介紹一下C語(yǔ)言如何使用mciSendString實(shí)現(xiàn)播放音樂(lè)功能,需要的可以參考一下
    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é)議,多個(gè)物聯(lián)網(wǎng)協(xié)議都是基于TCP協(xié)議的,這篇文章為大家介紹了Qt?TCP網(wǎng)絡(luò)通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Ubuntu 20.04 下安裝配置 VScode 的 C/C++ 開(kāi)發(fā)環(huán)境(圖文教程)

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

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

最新評(píng)論