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

C++中的虛函數

編輯:C++入門知識

終於放假了,可以想干嘛干嘛了,今天早上想到以前看過幾篇大神的博客,裡面提到說用父類的指針去訪問子類的函數。。今天早上沒什麼事,就來驗證一下。


[cpp] 
#include<iostream>  
using namespace std; 
class Base 

    public: 
    Base() 
    { 
        cout<<"initial Base Class"<<endl; 
    } 
    void name() 
    { 
        cout<<"Base Class name"<<endl; 
    } 
 
}; 
class Derived1:public Base 

    public: 
        Derived1() 
        { 
            cout<<"initial Derived Class"<<endl; 
        } 
        void name() 
        { 
            cout<<"Derived1 Class name"<<endl; 
        } 
}; 
int main() 

    Derived1 Derived1Class; 
    Derived1Class.name(); 
    //這個當然是可以正常運行的  
 
    Base* BaseClassPointer; 
    BaseClassPointer=(Base*)&Derived1Class; 
    BaseClassPointer->name(); 
    //這樣相當於把子類轉換為父類類型,然後去調用父類的name函數  
    return 0; 

#include<iostream>
using namespace std;
class Base
{
    public:
    Base()
    {
        cout<<"initial Base Class"<<endl;
    }
    void name()
    {
        cout<<"Base Class name"<<endl;
    }

};
class Derived1:public Base
{
    public:
        Derived1()
        {
            cout<<"initial Derived Class"<<endl;
        }
        void name()
        {
            cout<<"Derived1 Class name"<<endl;
        }
};
int main()
{
    Derived1 Derived1Class;
    Derived1Class.name();
    //這個當然是可以正常運行的

    Base* BaseClassPointer;
    BaseClassPointer=(Base*)&Derived1Class;
    BaseClassPointer->name();
    //這樣相當於把子類轉換為父類類型,然後去調用父類的name函數
    return 0;
}

運行結果


[cpp] 
initial Base Class       
initial Derived Class   //初始化Deerived類  
Derived1 Class name     //調用Derived類的name()  
Base Class name   //發生強制轉換,最終調用的是基類的name() 

initial Base Class     
initial Derived Class   //初始化Deerived類
Derived1 Class name     //調用Derived類的name()
Base Class name   //發生強制轉換,最終調用的是基類的name()
在不使用虛函數的情況下,用基類的指針去訪問子類的函數。這樣做就相當於把Derived1類型的對象強制轉換為Base類型的,所以函數最終調用的是基類中的name()函數。

使用虛函數就可以實現用基類的指針去訪問子類的函數,代碼如下:


[cpp] 
#include<iostream>  
using namespace std; 
class Base 

    public: 
        Base() 
        { 
            cout<<"initial Base Class"<<endl; 
        } 
        virtual void name()    //用虛函數來實現  
        { 
            cout<<"Base Class name"<<endl; 
        } 
        virtual ~Base() 
        { 
        } 
}; 
class Derived1:public Base 

    public: 
        Derived1() 
        { 
            cout<<"initial Derived Class"<<endl; 
        } 
        void name() 
        { 
            cout<<"Derived1 Class name"<<endl; 
        } 
        ~Derived1() 
        { 
        } 
}; 
int main() 

    Derived1 Derived1Class; 
    Derived1Class.name(); 
    //這個當然是可以正常運行的  
 
    Base* BaseClassPointer = (Base*)&Derived1Class; 
    BaseClassPointer->name(); 
    return 0; 

#include<iostream>
using namespace std;
class Base
{
    public:
        Base()
        {
            cout<<"initial Base Class"<<endl;
        }
        virtual void name()    //用虛函數來實現
        {
            cout<<"Base Class name"<<endl;
        }
        virtual ~Base()
        {
        }
};
class Derived1:public Base
{
    public:
        Derived1()
        {
            cout<<"initial Derived Class"<<endl;
        }
        void name()
        {
            cout<<"Derived1 Class name"<<endl;
        }
        ~Derived1()
        {
        }
};
int main()
{
    Derived1 Derived1Class;
    Derived1Class.name();
    //這個當然是可以正常運行的

    Base* BaseClassPointer = (Base*)&Derived1Class;
    BaseClassPointer->name();
    return 0;
}
運行結果:


[cpp] 
initial Base Class 
initial Derived Class     //初始化Derived類的兩個部分  
Derived1 Class name 
Derived1 Class name  //最終調用的是Derived類的name()  
 
Process returned 0 (0x0)   execution time : 0.018 s 
Press any key to continue. 

initial Base Class
initial Derived Class     //初始化Derived類的兩個部分
Derived1 Class name
Derived1 Class name  //最終調用的是Derived類的name()

Process returned 0 (0x0)   execution time : 0.018 s
Press any key to continue.

 

在類的繼承中,如果有基類指針指向派生類,那麼用基類指針delete時,如果不定義成虛函數,派生類中派生的那部分無法析構。

因此如果設計一個可能是基類的類時,最好將它的一個的析構函數設為虛函數,否則可能會造成內存洩露。

 

 

 

 

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