程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++中構造函數與析構函數能否為虛函數

C++中構造函數與析構函數能否為虛函數

編輯:C++入門知識

   看書時發現,C++中的基類的構造函數不能為虛函數(VC6.0中為虛函數是不能通過編譯的),析構函數應該為虛函數(MFC中CObject的析構函數即為虛函數)。
   通過以下面的代碼,來看看這樣的說法對不對:
   測試一:
Java代碼 
#include <iostream> 
using namespace std; 
 
class Base 

    public: 
        Base() 
        { 
            cout << "Base::Base()" <<endl; 
        } 
        ~Base() 
        { 
            cout << "Base::~Base()" <<endl; 
        } 
}; 
 
class Derived : public Base 

    public: 
        Derived() 
        { 
            cout << "Derived::Derived()" <<endl; 
        } 
        ~Derived() 
        { 
            cout << "Derived::~Derived()" <<endl; 
        } 
}; 
 
int main(int argc, char* argv[]) 

    Derived d;  // 依次調用Base::Base(),Derived::Derived() 
                // 程序結束時依次調用Derived::~Derived(),Base::~Base() 
    return 0;   // 注意現在基類的析構函數不是虛函數,但是按照調用順序不會造成內存洩露。 

    測試二:
Java代碼 
#include <iostream> 
using namespace std; 
 
class Base 

    public: 
        Base() 
        { 
            cout << "Base::Base()" <<endl; 
        } 
        ~Base() 
        { 
            cout << "Base::~Base()" <<endl; 
        } 
}; 
 
class Derived : public Base 

    public: 
        Derived() 
        { 
            cout << "Derived::Derived()" <<endl; 
        } 
        ~Derived() 
        { 
            cout << "Derived::~Derived()" <<endl; 
        } 
}; 
 
int main(int argc, char* argv[]) 
{    
    Derived *d2 = new Derived(); // 依次調用Base::Base(),Derived::Derived() 
    Base *pBase = d2;    
    delete pBase;                // 只調用了Base::~Base(),而沒有調用Derived::~Derived() 
                                 // 因為這裡基類的析構函數不是虛函數 
    return 0;    


    測試三:

Java代碼 
#include <iostream> 
using namespace std; 
 
class Base 

    public: 
        Base() 
        { 
            cout << "Base::Base()" <<endl; 
        } 
        virtual ~Base() 
        { 
            cout << "Base::~Base()" <<endl; 
        } 
}; 
 
class Derived : public Base 

    public: 
        Derived() 
        { 
            cout << "Derived::Derived()" <<endl; 
        } 
        ~Derived() 
        { 
            cout << "Derived::~Derived()" <<endl; 
        } 
}; 
 
int main(int argc, char* argv[]) 
{    
    Derived *d2 = new Derived(); // 依次調用Base::Base(),Derived::Derived() 
    Base *pBase = d2;    
    delete pBase;                // 依次調用Derived::~Derived(),Base::~Base(), 
                                 // 因為這裡基類的析構函數是虛函數 
    return 0;    


   總結:
         (1) 假如你不打算使用多態(用基類指針指向派生類實例),基類析構函數是否為虛函數是無關緊要的。
         (2) 假如你打算使用多態,一定要注意了,讓基類的析構函數為虛函數。
         PS: 對於非虛函數的調用,完全取決於指針的類型。因為非虛函數的地址在編譯階段就會根據指針的類型確定下來。舉一個簡單的例子,派生類有一個非虛函數f(),基類中不存在這樣的函數。使用一個基類指針指向一個派生類實例後,假如你打算使用這個基類指針調用f(),編譯器會讓你打消這個念頭(編譯無法通過)。

作者“icebergs”
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved