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

C++虛函數(shù)注意事項(xiàng)

 更新時(shí)間:2022年01月25日 16:42:15   作者:?梁唐  
這篇文章主要給大家分享了EC++虛函數(shù)注意事項(xiàng),

文章轉(zhuǎn)自公眾號(hào):Coder梁(ID:Coder_LT)

一、虛函數(shù)注意事項(xiàng)

在之前的文章當(dāng)中,我們已經(jīng)討論了虛函數(shù)的使用方法,也對(duì)它的原理進(jìn)行了簡(jiǎn)單的介紹。

這里簡(jiǎn)單做一個(gè)總結(jié):

  • 在基類的方法聲明中使用關(guān)鍵字virtual可以聲明虛函數(shù)
  • 加上了virtual關(guān)鍵字的函數(shù)在基類以及派生類和派生類再派生出來的類中都是虛的
  • 在調(diào)用虛函數(shù)時(shí),程序?qū)?huì)根據(jù)對(duì)象的類型執(zhí)行對(duì)應(yīng)的方法而非引用或指針的類型
  • 在定義基類時(shí),需要將要在派生類中重新定義的類方法聲明為虛,如析構(gòu)函數(shù)

除了這些之外,我們還有一些其他需要注意的事項(xiàng)。

1.構(gòu)造函數(shù)

構(gòu)造函數(shù)不能是虛函數(shù),創(chuàng)建派生類對(duì)象時(shí)將調(diào)用派生類的構(gòu)造函數(shù),而非基類的構(gòu)造函數(shù),畢竟構(gòu)造函數(shù)是根據(jù)類名調(diào)用的。

一般我們會(huì)在派生類中調(diào)用基類的構(gòu)造函數(shù),這其實(shí)不是繼承機(jī)制,所以將類構(gòu)造函數(shù)聲明為虛沒有意義。

2.析構(gòu)函數(shù)

前文說過析構(gòu)函數(shù)應(yīng)該是虛函數(shù),除非類不被繼承。

因?yàn)榕缮惍?dāng)中往往含有獨(dú)有的成員變量,如果析構(gòu)函數(shù)非虛,那么會(huì)導(dǎo)致在對(duì)象析構(gòu)時(shí)僅調(diào)用基類的析構(gòu)函數(shù),從而導(dǎo)致獨(dú)有的成員變量?jī)?nèi)存不被釋放,引起內(nèi)存泄漏。

所以通常我們會(huì)將析構(gòu)函數(shù)設(shè)置成virtual,即使不用做基類也不會(huì)引起錯(cuò)誤,至多只會(huì)影響一點(diǎn)效率。但在大型合作開發(fā)的項(xiàng)目當(dāng)中,許多組件和類都是共享的,我們往往無法保證我們開發(fā)的類是否會(huì)被其他開發(fā)者繼承,因此設(shè)置虛析構(gòu)函數(shù)也是一種常規(guī)做法。

3.友元

友元函數(shù)不能是虛函數(shù),因?yàn)橛言皇穷惓蓡T,只有成員函數(shù)才能是虛函數(shù)。

如果我們希望友元函數(shù)也能實(shí)現(xiàn)類似虛函數(shù)的功能, 我們可以在友元函數(shù)當(dāng)中使用虛函數(shù)來解決。

4.沒有重新定義

如果派生類當(dāng)中沒有重新定義虛函數(shù),那么將使用該函數(shù)的基類版本。如果派生類位于派生鏈中,如B繼承了A,C繼承了B這種情況,那么派生類將會(huì)使用最新的虛函數(shù)版本。

5.重新定義將隱藏方法

我們來看一個(gè)例子:

class Mammal {
?private:
? string name;
?public:
? Mammal(string n): name(n) {}
? virtual void speak() const {
? ?cout << "can't say anything" << endl;
? }
};

class Human : public Mammal{
?private:
? string job;
?public:
? Human(string n, string j): Mammal(n), job(j) {}
? virtual void speak(const string st) const {
? ?cout << "i'm human" << endl;
? }
};

我們?cè)诟割惍?dāng)中定義了一個(gè)無參虛函數(shù)speak,而在子類Human當(dāng)中也定義了一個(gè)需要傳入一個(gè)string類型的虛函數(shù)speak

我試了一下,在我的g++編譯器當(dāng)中,會(huì)報(bào)錯(cuò):

但根據(jù)C++ Primer中的說法,在一些古老的編譯器當(dāng)中,可能不會(huì)報(bào)錯(cuò),甚至可能連警告都沒有。

在這類編譯器當(dāng)中,我們重新定義父類中的虛函數(shù),這樣的重新定義不會(huì)生成兩個(gè)重載版本,而是隱藏了父類無參的版本,只保留了接受string類型的版本,這種情況有別于函數(shù)重載。

在派生類當(dāng)中重新定義函數(shù),不是使用相同的函數(shù)特征標(biāo)覆蓋基類聲明,而是隱藏同名的基類方法,不管函數(shù)特征標(biāo)如何。

C++ Primer當(dāng)中給出了兩條經(jīng)驗(yàn)規(guī)則:

如果重新定義繼承的方法,應(yīng)該保證與原來的原型完全相同,唯一的例外是返回的類型,如果基類返回的是基類的引用或指針,派生類可以改成派生類的引用或指針:

class Mammal {
?private:
? string name;
?public:
? Mammal(string n): name(n) {}
? virtual Mammal* build();
};

class Human : public Mammal{
?private:
? string job;
?public:
? Human(string n, string j): Mammal(n), job(j) {}
? virtual Human* build();
};

如果基類聲明被重載了,那么應(yīng)該在派生類中聲明所有的基類版本:
 

class Mammal {
?private:
? string name;
?public:
? Mammal(string n): name(n) {}
? virtual void speak() const ;
? ? ?virtual void speak(int n) const;
? ? ?virtual void speak(const string st) const;
};

class Human : public Mammal{
?private:
? string job;
?public:
? Human(string n, string j): Mammal(n), job(j) {}
? virtual void speak() const ;
? ? ?virtual void speak(int n) const;
? ? ?virtual void speak(const string st) const;
};

如果我們只重新定義了一個(gè)版本,那么另外兩個(gè)版本將隱藏。

但這可能和編譯器版本有關(guān),在新版的編譯器當(dāng)中似乎取消了這一設(shè)定。

我嘗試了一下,發(fā)現(xiàn)并不會(huì)隱藏,一樣可以順利調(diào)用父類方法。

class Mammal {
?private:
? string name;
?public:
? Mammal(string n): name(n) {}
? virtual void speak() const {
? ?cout << "can't say anything from empty" << endl;
? }
? virtual void speak(const string st) const {
? ?cout << "can't say anything from string input" << endl;
? }
};

class Human : public Mammal{
?private:
? string job;
?public:
? Human(string n, string j): Mammal(n), job(j) {}
? virtual void speak(const string st) const {
? ?cout << "i'm human" << endl;
? }
};

int main() {
?Mammal *m = new Human("man", "spiderman");
?m->speak();
?return 0;
}

到此這篇關(guān)于EC++虛函數(shù)注意事項(xiàng)的文章就介紹到這了,更多相關(guān)EC++虛函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中的數(shù)字轉(zhuǎn)字符串to_string

    C++中的數(shù)字轉(zhuǎn)字符串to_string

    這篇文章主要介紹了C++中的數(shù)字轉(zhuǎn)字符串to_string,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Qt 使用QDialog實(shí)現(xiàn)界面遮罩的示例(蒙版)

    Qt 使用QDialog實(shí)現(xiàn)界面遮罩的示例(蒙版)

    界面遮罩在很多時(shí)候都可以用到,例如彈窗,本文主要介紹了Qt 使用QDialog實(shí)現(xiàn)界面遮罩的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 教你用Matlab制作立體動(dòng)態(tài)相冊(cè)

    教你用Matlab制作立體動(dòng)態(tài)相冊(cè)

    沒想到吧,MATLAB竟也能制作3D相冊(cè)!本文將為大家詳細(xì)介紹Matlab制作立體動(dòng)態(tài)相冊(cè)的方法步驟,感興趣的小伙伴可以跟隨小編一起動(dòng)手試一試
    2022-03-03
  • 讓我們一起來對(duì)C語言指針再分析

    讓我們一起來對(duì)C語言指針再分析

    這篇文章主要為大家詳細(xì)介紹C語言的指針,本文進(jìn)行了深度解析,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別

    OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別

    這篇文章主要為大家詳細(xì)介紹了OpenCV + MFC實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • C語言詳細(xì)分析講解struct與union使用方法

    C語言詳細(xì)分析講解struct與union使用方法

    最近開始自學(xué)C語言,從最基礎(chǔ)部分的開始學(xué)起。今天看書的時(shí)候注意到了struct和union似乎很像,除了名字不同,看起來幾乎沒有區(qū)別。<BR>既然C中定義了struct和union兩個(gè)關(guān)鍵字,那么它們肯定是有區(qū)別的,在查了一些資料之后我來總結(jié)一下他們的使用
    2022-04-04
  • C++實(shí)現(xiàn)高校教室管理系統(tǒng)

    C++實(shí)現(xiàn)高校教室管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)高校教室管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C/C++ 中sizeof(''a'')對(duì)比詳細(xì)介紹

    C/C++ 中sizeof(''a'')對(duì)比詳細(xì)介紹

    這篇文章主要介紹了C/C++ 中sizeof('a')的值對(duì)比詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • C語言版三子棋游戲

    C語言版三子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語言版三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 用c++實(shí)現(xiàn)x的y次冪的代碼

    用c++實(shí)現(xiàn)x的y次冪的代碼

    以下實(shí)例是對(duì)使用c++實(shí)現(xiàn)x的y次冪的解決方法進(jìn)行了介紹。需要的朋友參考下
    2013-05-05

最新評(píng)論