1. 程式人生 > >虛擬函式,靜態與動態繫結

虛擬函式,靜態與動態繫結

正好複習到了這部分,整理一下,主要是翻譯課件。

虛擬函式和指標結合使用可以產生最大的效果。

1. 非虛擬函式是靜態繫結的;

2. 虛擬函式可能(may)是動態繫結的;

3. 一個指標實際上可能指向了衍生類物件,當虛擬函式被指標呼叫時,繫結哪個函式取決於被指物件的類,而不是指標的型別;

4. 所以,虛擬函式根據執行函式的型別(接收者,the receiver) 來繫結。

靜態繫結和動態繫結的區別:

1. 動態繫結:只有在程式執行時才能決定呼叫哪個函式;

2. 靜態繫結:編譯時就可以決定呼叫哪個函式;

3. C++中,如果接收者是個指標則虛擬函式動態繫結(例如:如果f(...)為虛擬函式,則pointer->f(...)動態繫結);

4. 其他函式都是靜態繫結。

虛擬函式和過載函式的區別:(轉自:http://blog.csdn.net/livelylittlefish/article/details/2171515,我覺得這個程式解釋的很清楚)

1. 過載函式在型別和引數數量上一定不相同,而重定義的虛擬函式則要求引數的型別和個數、函式返回型別相同;
2. 虛擬函式必須是類的成員函式,過載的函式則不一定是這樣;
3. 建構函式可以過載,但不能是虛擬函式,解構函式可以是虛擬函式。

例1:

#include <iostream.h>
class CBase
{
public:
    
virtualint func(unsigned 
char ch) {return--ch;}
}
;
class CDerive : public CBase
{
    
int func(char ch) {return++ch;}//此為函式過載
}
;
void main()
{    CBase *p=new CDerive;
    
int n=p->func(40);        //呼叫基類的 func()
    cout<<" the result is : "<<n<<endl;
}
執行結果:        the result is : 39

例2:

#include <iostream.h
>
class CBase
{
public:
    
virtualint func(unsigned char ch) {return--ch;}
}
;
class CDerive : public CBase
{
    
int func(unsigned char ch) {return++ch;}//此為虛擬函式
}
;
void main()
{    CBase *p=new CDerive;
    
int n=p->func(40);        //呼叫派生類的 func()
    cout<<" the result is : "<<n<<endl;
}
執行結果:         the result is : 41

這個例子可以驗證

“ 3. 一個指標實際上可能指向了衍生類物件,當虛擬函式被指標呼叫時,繫結哪個函式取決於被指物件的類,而不是指標的型別;