日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++:类-多态的学习和使用

發(fā)布時間:2025/3/20 c/c++ 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++:类-多态的学习和使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C++:類的學(xué)習(xí)和使用

  • 類的多態(tài)
  • 1.類的實(shí)例化
  • 1.類中虛函數(shù)的使用實(shí)現(xiàn)多態(tài)
  • C++ override使用詳解

類的多態(tài)

類作用域操作符 ::

C++是面向?qū)ο蟮木幊陶Z言,多態(tài)的使用是父類與子類關(guān)系最直接的表現(xiàn):
c++中對于多態(tài)的理解就好比如下一個例子:
①我們說一種有四條腿的動物A,并進(jìn)行簡單描述有四條腿的特征;
②甲猜了一種動物B,并且說了四條腿的具體特征;
③乙猜了一種動物C,并且說了四條腿的具體特征;

如上:動物A可以理解為基類,動物B.C都是子類,所以類的多態(tài)就表現(xiàn)在四條腿的特征(父類的(純)虛函數(shù))上 B和C都繼承了A四條腿的特征,至于B和C因?yàn)楦髯晕锓N差異而有所不同就對應(yīng)了具體的子類中的(純)虛函數(shù)定義。

https://blog.csdn.net/lling_shan/article/details/105947287
分類:
靜態(tài)多態(tài)
:靜態(tài)多態(tài)是編譯器在編譯期間完成的,編譯器會根據(jù)實(shí)參類型來選擇調(diào)用合適的函數(shù),如果有合適的函數(shù)可以調(diào)用就調(diào),沒有的話就會發(fā)出警告或者報錯。
動態(tài)多態(tài)
:程序運(yùn)行時根據(jù)基類的引用(指針)指向的對象來確定自己具體該調(diào)用哪一個類的虛函數(shù)

靜態(tài)多類:

/** 程序名:book236.cpp,此程序用于演示C++類的靜態(tài)多態(tài)。* 作者:C語言技術(shù)網(wǎng)(www.freecplus.net) 日期:20190525 */ #include <stdio.h> #include <string.h>class CGirl // 定義超女類 { public:char m_name[50]; // 姓名int m_age; // 年齡int m_height; // 身高,單位:厘米cmchar m_sc[30]; // 身材,火辣;普通;飛機(jī)場。char m_yz[30]; // 顏值,漂亮;一般;歪瓜裂棗。int Show() // 顯示超女基本信息的成員函數(shù)體{ printf("姓名:%s,年齡:%d,身高:%d,身材:%s,顏值:%s\n",m_name,m_age,m_height,m_sc,m_yz); } };class CKCon:public CGirl // 定義王妃類,從超女類繼承 { public:char m_ch[50]; // 稱號char m_palace[50]; // 居住的宮殿int m_sal; // 奉祿int Show() // 顯示王妃的稱號、宮殿和奉祿{ printf("姓名:%s,稱號:%s,棲:%s,奉祿:%d兩銀子。\n",m_name,m_ch,m_palace,m_sal); } };int main() {CKCon KCon;strcpy(KCon.m_name,"楊玉環(huán)"); KCon.m_age=28; KCon.m_height=168;strcpy(KCon.m_sc,"火辣"); strcpy(KCon.m_yz,"漂亮"); strcpy(KCon.m_ch,"楊貴妃");strcpy(KCon.m_palace,"華清宮"); KCon.m_sal=10000;CGirl *pGirl; // 基類的指針CKCon *pCon; // 派生類的指針pGirl=pCon=&KCon; // 都指向派生類pGirl->Show(); // 將調(diào)用的是基類的Show方法pCon->Show(); // 將調(diào)用的是派生類的Show方法 }

輸出結(jié)果:

main函數(shù)中,創(chuàng)建的是CKCon對象,如果采用基類指針調(diào)用Show方法,變成了調(diào)用CGirl類的Show方法,而不是CKcon類的Show方法,因?yàn)閜Girl是CGirl的指針,pGirl->Show方法在程序編譯期間就已經(jīng)設(shè)置好了。

動態(tài)多態(tài):
動態(tài)多態(tài)是在程序運(yùn)行時根據(jù)基類的引用(指針)指向的對象來確定自己具體該調(diào)用哪一個類的虛函數(shù)。

讓我們對程序稍作修改,在CGirl類中,Show方法的聲明前放置關(guān)鍵字 virtual,如下所示:

virtual int Show() // 顯示超女基本信息的成員函數(shù)體

其它的代碼都不變,編譯并運(yùn)行,結(jié)果如下:

此時,編譯器看的是指針的內(nèi)容,而不是它的類型。這就是多態(tài)的一般使用方式。

1.類的實(shí)例化

https://blog.csdn.net/qq_34637408/article/details/71189382

1.類中虛函數(shù)的使用實(shí)現(xiàn)多態(tài)

①類的多態(tài)
②1.首先看成員函數(shù)所在的類是否會作為基類。然后看成員函數(shù)在類的繼承后有無可能被更改功能,如果希望更改其功能的,一般應(yīng)該將它聲明為虛函數(shù)。

  • 如果成員函數(shù)在類被繼承后功能不需修改,或派生類用不到該函數(shù),則不要把它聲明為虛函數(shù)。不要僅僅考慮到要作為基類而把類中的所有成員函數(shù)都聲明為虛函數(shù)。
  • 3、應(yīng)考慮對成員函數(shù)的調(diào)用時通過對象名還是通過基類指針或引用去訪問,如果是通過基類指針或引用去訪問的,則應(yīng)當(dāng)聲明為虛函數(shù)。

    4.有時,在定義虛函數(shù)時,并不定義去函數(shù)體,即函數(shù)體是空的。它的作用只是定義了一個虛函數(shù)名,具體功能留給派生類去添加。

    使用虛函數(shù),系統(tǒng)要有一定的空間開銷。當(dāng)一個類帶有虛函數(shù)時,編譯系統(tǒng)會為該類構(gòu)造一個虛函數(shù)表,它是一個指針數(shù)組,存放每個虛函數(shù)的入口地址。系統(tǒng)在進(jìn)行動態(tài)關(guān)聯(lián)時的時間開銷時很小的,因此,多態(tài)性時高效的。

    原文鏈接:https://blog.csdn.net/wshngyf/article/details/48092679

    純虛函數(shù)

    一、定義
      純 虛函數(shù) 是一種特殊的虛函數(shù),它的一般格式如下:

    class <類名>{virtual <類型><函數(shù)名>(<參數(shù)表>)=0;};

    在許多情況下,在基類中不能對虛函數(shù)給出有意義有實(shí)現(xiàn),而把它說明為純虛函數(shù),它的實(shí)現(xiàn)留給該基類的派生類去做。這就是純虛函數(shù)的作用。
      
    二、引入原因
      1、為了方便使用 多態(tài) 特性,我們常常需要在基類中定義虛擬函數(shù)。
      2、在很多情況下,基類本身生成對象是不合情理的。
      例如,動物作為一個基類可以派生出老虎、孔雀等子類,但動物本身生成對象明顯不合常理。
      為了解決上述問題,引入了純虛函數(shù)的概念,將函數(shù)定義為純虛函數(shù)(方法:virtual ReturnType Function()= 0;),則編譯器要求在派生類中必須予以重載以實(shí)現(xiàn)多態(tài)性。同時含有純虛擬函數(shù)的類稱為 抽象類 ,它不能生成對象。這樣就很好地解決了上述兩個問題。
    三、相似概念
      1、多態(tài)性
      指相同對象收到不同消息或不同對象收到相同消息時產(chǎn)生不同的實(shí)現(xiàn)動作。
      C++支持兩種多態(tài)性:編譯時多態(tài)性,運(yùn)行時多態(tài)性。
      a.編譯時多態(tài)性:通過重載函數(shù)實(shí)現(xiàn)
      b 運(yùn)行時多態(tài)性:通過虛函數(shù)實(shí)現(xiàn)。

      2、虛函數(shù)
      虛函數(shù)是在基類中被聲明為virtual,并在派生類中重新定義的成員函數(shù),可實(shí)現(xiàn)成員函數(shù)的動態(tài)重載
      3、抽象類
      包含純虛函數(shù)的類稱為抽象類
      由于抽象類包含了沒有定義的純虛函數(shù),所以不能定義抽象類的對象。
      
    注意:
    (1)純虛函數(shù)沒有函數(shù)體;
    (2)最后面的“=0”并不表示函數(shù)返回值為0,它只起形式上的作用,告訴編譯系統(tǒng)“這是虛函數(shù)”;
    (3)這是一個聲明語句,最后有分號。
    純虛函數(shù)只有函數(shù)的名字而不具備函數(shù)的功能,不能被調(diào)用。
    純虛函數(shù)的作用是在基類中為其派生類保留一個函數(shù)的名字,以便派生類根據(jù)需要對他進(jìn)行定義。如果在基類中沒有保留函數(shù)名字,則無法實(shí)現(xiàn)多態(tài)性。
    如果在一個類中聲明了純虛函數(shù),在其派生類中沒有對其函數(shù)進(jìn)行定義,則該虛函數(shù)在派生類中仍然為純虛函數(shù)。

    抽象類:
    不用定義對象而只作為一種基本類型用作繼承的類叫做抽象類(也叫接口類),凡是包含純虛函數(shù)的類都是抽象類,抽象類的作用是作為一個類族的共同基類,為一個類族提供公共接口,抽象類不能實(shí)例化出對象。
    純虛函數(shù)在派生類中重新定義以后,派生類才能實(shí)例化出對象。
    總結(jié):
    1、派生類重寫基類的虛函數(shù)實(shí)現(xiàn)多態(tài),要求函數(shù)名、參數(shù)列表、返回值完全相同。(協(xié)變除外)
    2、基類中定義了虛函數(shù),在派生類中該函數(shù)始終保持虛函數(shù)的特性。
    3、只有類的非靜態(tài)成員函數(shù)才能定義為虛函數(shù),靜態(tài)成員函數(shù)不能定義為虛函數(shù)。
    4、如果在類外定義虛函數(shù),只能在聲明函數(shù)時加virtual關(guān)鍵字,定義時不用加。
    5、構(gòu)造函數(shù)不能定義為虛函數(shù),雖然可以將operator=定義為虛函數(shù),但最好不要這么做,使用時容易混淆
    6、不要在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù),在構(gòu)造函數(shù)和析構(gòu)函數(shù)中,對象是不完整的,可能會出現(xiàn)未定義的行為。
    7、最好將基類的析構(gòu)函數(shù)聲明為虛函數(shù)。(析構(gòu)函數(shù)比較特殊,因?yàn)榕缮惖奈鰳?gòu)函數(shù)跟基類的析構(gòu)函數(shù)名稱不一樣,但是構(gòu)成覆蓋,這里編譯器做了特殊處理)
    8、虛表是所有類對象實(shí)例共用的虛表剖析。

    原文鏈接:https://blog.csdn.net/qq_36221862/article/details/61413619

    class A{public:A();virtual ~A();void f1();virtual void f2();virtual void f3()=0;};//子類:class B : public A{public:B();virtual ~B();void f1();virtual void f2();virtual void f3();};// main 函數(shù):int main(int argc, char* argv[]){A *m_j=new B();m_j->f1();m_j->f2();m_j->f3();delete m_j;return 0;}

    f1()是一個隱藏,關(guān)于函數(shù)的隱藏,可以參考其它詞條.
    調(diào)用m_j->f1();會去調(diào)用A類中的f1(),它是在我們寫好代碼的時候就會定好的.
    也就是根據(jù)它是由A類定義的,這樣就調(diào)用這個類的函數(shù).
    f2()是普通的重載.
    調(diào)用m_j->f2();會調(diào)用m_j中到底保存的對象中,對應(yīng)的這個函數(shù).這是由于new的B對象.
    f3()與f2()一樣,只是在基類中不需要寫函數(shù)實(shí)現(xiàn).

    虛函數(shù)和抽象基類的應(yīng)用:

    #include <iostream> using namespace std;//聲明抽象基類Shape class Shape { public:virtual float area()const //虛函數(shù){return 0.0;}virtual void shapeName()const = 0;//純虛函數(shù)//shapeNamea函數(shù)的作用是輸出具體的形狀,在派生類中定義,因此聲明為純虛函數(shù) };//聲明Point類 class Point:public Shape { public:Point(float a = 0.0, float b = 0.0){x = a;y = b;}void setPoint(float a, float b){x = a;y = b;}float getX()const{return x;}float getY()const{return y;}virtual void shapeName()const{cout<<"Point:";}friend ostream & operator <<(ostream &_cout, const Point &p){_cout<<"["<<p.x<<","<<p.y<<"]";return _cout;}protected:float x;float y; };//聲明Ciircle類 class Circle:public Point { public:Circle(float a = 0.0, float b = 0.0, float r = 0.0):Point(a, b),radius(r){}void setRadius(float r){radius = r;}float getRadius()const{return radius;}virtual float area()const{return 3.1415926*radius*radius;}virtual void shapeName()const{cout<<"Circle:";}friend ostream & operator <<(ostream &_cout, const Circle &c){_cout<<"["<<c.x<<","<<c.y<<"],r="<<c.radius;return _cout;}protected:float radius; };int main() {Point point(3.2, 4.5); // 建立Point類對象pointCircle circle(2.4, 1.2, 5.6); //建立Circle類對象circlepoint.shapeName(); //靜態(tài)關(guān)聯(lián)cout<<point<<endl;circle.shapeName(); //靜態(tài)關(guān)聯(lián)cout<<circle<<endl;Shape* pt; //定義基類指針pt = &point;pt->shapeName();cout<<"x="<<point.getX()<<",y="<<point.getY()<<endl;cout<<"area="<<pt->area()<<endl;pt = &circle; //指針指向Circle類對象pt->shapeName(); //動態(tài)關(guān)聯(lián)cout<<"x="<<circle.getX()<<",y="<<circle.getY()<<endl;cout<<"area="<<pt->area()<<endl;system("pause");return 0; }

    運(yùn)行結(jié)果

    結(jié)論:
    (1)一個基類如果包含一個或一個以上純虛函數(shù),就是抽象基類。抽象基類不能也沒必要定義對象。
    (2)在類的層次結(jié)構(gòu)中,頂層或最上面幾層可以是抽象基類。抽象基類體現(xiàn)了本類族中各類的共性,把各類中共有的成員函數(shù)集中在抽象基類中聲明。
    (3)抽象基類是本類族的共公共接口,即就是從同一基類中派生出的多個類有同一接口。

    原文鏈接:https://blog.csdn.net/qq_36221862/article/details/61413619

    C++ override使用詳解

    C++ override從字面意思上,是覆蓋的意思,實(shí)際上在C++中它是覆蓋了一個方法并且對其重寫,從而達(dá)到不同的作用。在我們C++編程過程中,最熟悉的就是對接口方法的實(shí)現(xiàn),在接口中一般只是對方法進(jìn)行了聲明,而我們在實(shí)現(xiàn)時,就需要實(shí)現(xiàn)接口聲明的所有方法。還有一個典型應(yīng)用就是在繼承中也可能會在子類覆蓋父類的方法。

    原文鏈接:https://blog.csdn.net/fanyun_01/article/details/79122136

    總結(jié)

    以上是生活随笔為你收集整理的C++:类-多态的学习和使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。