1. 程式人生 > 實用技巧 >解構函式與虛擬函式

解構函式與虛擬函式

解構函式與虛擬函式

程式碼一
#include<iostream>
using namespace std;
class ClxBase{
public:
    ClxBase() {};
    ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;};

    void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};

class ClxDerived : public ClxBase{
public:
    ClxDerived() {};
   ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };

    void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};
  int  main(){  
  ClxDerived *p =  new ClxDerived;
  p->DoSomething();
  delete p;
  return 0;
  }
輸出一
Do something in class Derived!
Output from the destructor of class Derived!
Output from the destructor of class Base!
說明一

基類解構函式不是虛擬函式。main函式中使用派生類的指標操作派生類的成員。釋放指標p的順序是:

先釋放派生類的資源,再釋放基類的資源。

程式碼二
#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;
}
輸出二
Do something in class Base!
Output from the destructor of class Base!
說明二

基類解構函式不是虛擬函式,在main函式中使用基類指標操作派生類的成員。釋放指標p的順序是:釋放基類的資源。(呼叫Dosomething()也是基類的版本)

派生類的資源沒有得到釋放會造成記憶體洩漏。

public繼承,基類對派生類的操作,只能影響到從基類繼承下來的成員。若是基類對非繼承成員操作,需要將這個函式定義成虛擬函式。

程式碼三
#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;
}
輸出三
Do something in class Derived!
Output from the destructor of class Derived!
Output from the destructor of class Base!
說明三

基類的解構函式與Domething()定義為虛擬函式,main()函式中使用基類指標操作派生類的成員。釋放指標p的順序是,釋放繼承類的資源,再呼叫基類的解構函式。

後記

若不需要基類對派生類及其物件進行操作,則不需要虛擬函式,這樣會增加記憶體開銷。因為虛擬函式會導致類維護一個虛擬函式表,裡邊存放虛擬函式指標。

參考:

解構函式什麼情況下要定義為虛擬函式?