国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

淺談C++基類的析構(gòu)函數(shù)為虛函數(shù)

2020-01-26 14:50:35
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

1、原因:

   在實(shí)現(xiàn)多態(tài)時(shí), 當(dāng)用基類指針操作派生類, 在析構(gòu)時(shí)候防止只析構(gòu)基類而不析構(gòu)派生類。

2、例子:

  (1)、

    #include<iostream>  using namespace std;  class Base{  public:     Base() {};    ~Base() {cout << "Output from the destructor of class Base!" << endl;};    void DoSomething() { cout << "Do something in class Base!" << endl; };  };  class Derived : public Base{  public:     Derived() {};    ~Derived() { cout << "Output from the destructor of class Derived!" << endl; };    void DoSomething() { cout << "Do something in class Derived!" << endl; };  };  int  main(){      Derived* p = new Derived;     p->DoSomething();     delete p;     return 0;   }

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

  Do something in class Derived!           

  Output from the destructor of class Derived!

  Output from the destructor of class Base! 

  代碼中基類的析構(gòu)函數(shù)不是虛函數(shù),在main函數(shù)中用繼承類的指針去操作繼承類的成員,釋放指針P的過(guò)程是:先釋放繼承類的資源,再釋放基類資源。

  (2)、

   #include<iostream>  using namespace std;  class Base{  public:     Base() {};    ~Base() {cout << "Output from the destructor of class Base!" << endl;};    void DoSomething() { cout << "Do something in class Base!" << endl; };  };  class Derived : public Base{  public:     Derived() {};    ~Derived() { cout << "Output from the destructor of class Derived!" << endl; };    void DoSomething() { cout << "Do something in class Derived!" << endl; };  };  int  main(){      Base* p = new Derived;     p->DoSomething();     delete p;     return 0;   }

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

    Do something in class ClxBase!
    Output from the destructor of class ClxBase!

      代碼中基類的析構(gòu)函數(shù)同樣不是虛函數(shù),不同的是在main函數(shù)中用基類的指針去操作繼承類的成員,釋放指針P的過(guò)程是:只釋放基類的資源,而沒(méi)有調(diào)用繼承類的析構(gòu)函數(shù)。 調(diào)用DoSomething()函數(shù)執(zhí)行的也是基類定義的函數(shù)。

      一般情況下,這樣的刪除只能夠刪除基類對(duì)象,而不能刪除子類對(duì)象,形成了刪除一半形象,造成內(nèi)存泄漏。

      在公有繼承中,基類對(duì)派生類及其對(duì)象的操作,只能影響到那些從基類繼承下來(lái)的成員。如果想要用基類對(duì)非繼承成員進(jìn)行操作,則要把基類的這個(gè)函數(shù)定義為虛函數(shù)。 析構(gòu)函數(shù)自然也應(yīng)該如此:如果它想析構(gòu)子類中的重新定義或新的成員及對(duì)象,當(dāng)然也應(yīng)該聲明為虛的。

   (3)、

  #include<iostream>  using namespace std;  class Base{  public:     Base() {};    virtual ~Base() {cout << "Output from the destructor of class Base!" << endl;};    virtual void DoSomething() { cout << "Do something in class Base!" << endl; };  };  class Derived : public Base{  public:     Derived() {};    ~Derived() { cout << "Output from the destructor of class Derived!" << endl; };    void DoSomething() { cout << "Do something in class Derived!" << endl; };  };  int  main(){      Base* p = new Derived;     p->DoSomething();     delete p;     return 0;   }

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

    Do something in class ClxDerived!
    Output from the destructor of class ClxDerived!
    Output from the destructor of class ClxBase!

    代碼中基類的析構(gòu)函數(shù)被定義為虛函數(shù),在main函數(shù)中用基類的指針去操作繼承類的成員,釋放指針P的過(guò)程是:釋放了繼承類的資源,再調(diào)用基類的析構(gòu)函數(shù)。調(diào)用DoSomething()函數(shù)執(zhí)行的也是繼承類定義的函數(shù)。

3、總結(jié):

  基類指針可以指向派生類的對(duì)象(多態(tài)性),如果刪除該指針delete p;就會(huì)調(diào)用該指針指向的派生類析構(gòu)函數(shù),而派生類的析構(gòu)函數(shù)又自動(dòng)調(diào)用基類的析構(gòu)函數(shù),這樣整個(gè)派生類的對(duì)象完全被釋放。如果析構(gòu)函數(shù)不被聲明成虛函數(shù),則編譯器實(shí)施靜態(tài)綁定,在刪除基類指針時(shí),只會(huì)調(diào)用基類的析構(gòu)函數(shù)而不調(diào)用派生類析構(gòu)函數(shù),這樣就會(huì)造成派生類對(duì)象析構(gòu)不完全。所以,將析構(gòu)函數(shù)聲明為虛函數(shù)是十分必要的。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 阜阳市| 奉新县| 依安县| 扎兰屯市| 贵港市| 新建县| 临桂县| 德惠市| 凯里市| 商城县| 石阡县| 德清县| 永吉县| 抚松县| 永新县| 将乐县| 乐平市| 双辽市| 大兴区| 新源县| 图木舒克市| 唐河县| 长兴县| 琼结县| 昭觉县| 漳浦县| 万山特区| 孝感市| 涞源县| 万州区| 南皮县| 德安县| 青冈县| 普宁市| 印江| 稷山县| 屏东市| 措勤县| 罗源县| 教育| 会理县|