2011-08-20 73 views
1

我想我的問題應該是愚蠢的,但我從來沒有見過一個聲明爲虛函數的函數指針。是否有一個原因?函數指針和虛函數

編輯:

我應該說:這是可能的功能它指向被指定爲虛擬?

+0

我編輯,請閱讀並幫助我 –

+0

對我仍然沒有意義。但答案是,將函數指針聲明爲虛擬是非法的。即使指向的成員函數是虛擬的。只是測試了這個,並得到了錯誤信息「虛擬」不允許數據聲明「這是一個很好的錯誤消息,我認爲。 – john

+0

請閱讀其他文章和評論。 :-) –

回答

5

嗯,是(和否)。

普通函數指針不能指向非靜態成員函數。他們只能指向獨立函數,這就是爲什麼普通函數指針的功能虛擬性問題甚至沒有出現在圖片中。

爲了指向C++中的成員函數,您需要一個特殊類型的指針:一個指針指向成員函數類型。這種類型的指針可以指向非虛擬成員函數,也可以指向虛擬成員函數。如果你想指向虛擬成員函數,沒有特殊的步驟。例如

struct B { 
    virtual void foo() {} 
    void bar() {} 
}; 

... 
B b; 
void (B::*pfunc)(); // declare a pointer to a member function 

pfunc = &B::foo; // make it point to `B::foo` 
(b.*pfunc)(); // calls `B::foo` for object `b` 

pfunc = &B::bar; // make it point to `B::bar` 
(b.*pfunc)(); // calls `B::bar` for object `b` 

然而,當你做出這樣的指針指向一個虛成員函數,你要記住,它並沒有真正得到綁在類層次結構功能的特定版本。有關具體呼叫功能的決定是在呼叫時進行的。例如

// given the above `B` 
struct D : B { 
    virtual void foo() {} 
}; 

... 
void (B::*pfoo)(); // declare a pointer to a member function 
pfoo = &B::foo; // and make it point to `B::foo` 

在上面的例子中,我們做出來的指針pfoo指向B::foo。或者我們?實際上,該指針並不是與B::foo特別固定鏈接的。這兩個電話

B b; 
D d; 

(b.*pfoo)(); 
(d.*pfoo)(); 

將調用兩個不同的功能。第一個將調用B::foo作爲對象b,而第二個將調用D::foo作爲對象d,即使我們在兩種情況下都使用了相同的指針值。這在許多應用中都很有意義。

但是,在某些低級別情況下,有一個與特定版本的虛擬函數聯繫緊密的指針會很有用。即這將是很好有一個指針,將調用B::fooB子對象的對象d當我們做

(d.*pfoo)(); 

爲了實現這個目標,我們需要能夠指定我們是否要早期綁定它的(在點初始化)或遲到(在通話時)。不幸的是,C++語言沒有提供這樣的功能。

+0

謝謝,儘管我無法全面瞭解您實際告訴我的內容,但我想接受您的有用答覆作爲解決方案。 :-D –

2

函數指針只是指向函數的指針。它只是存儲一個函數的地址,就像指向一個類型的存儲地址的指針一樣。

關鍵字virtual用於通過動態調度實現多態行爲(基類和派生類的函數之間)。

鑑於上述兩者是截然不同的,函數指針爲虛擬的想法根本沒有意義。

它指向的函數是否被指定爲虛擬的?
正如我前面提到的,函數指針只是存儲函數的地址。這只是一個type。爲例如:

int *i = NULL; 
void doSomething(); 
typedef void(*ptr)() = NULL; 
ptr = &doSomething(); 

在上面的例子:
i是一種類型的int *。同樣,
ptr是一種可以存儲不帶參數並且不返回參數的函數的地址的類型。

所以,從根本上說,您可以將函數指針指向的函數作爲虛函數,就像通過在類中聲明特定函數爲虛函數來使任何函數虛擬化一樣。

函數指針是一個類型可以指向與該原型任何功能,同時聲明一個函數爲具有在特定功能啓用,當你看都是不相同的動態調度虛擬裝置。

+0

我編輯我的帖子。謝謝 –

+0

@今晚吃什麼:更新答案回答您的問題 –

+0

謝謝您的建議。無論如何我都刪除了它。我現在在吃飯,請在我吃完飯後繼續在線等待我的下一個問題。我希望你能提供一些有用的幫助。 –

1

虛擬性是成員函數的一個屬性。如果你有一個指向虛擬成員函數的指針,那麼虛擬調用將自動進行。常規函數不能是虛擬的,所以虛函數指針是沒有意義的。在任何一種情況下,使函數指針都是虛擬的沒有意義,因爲它指向的函數被指向。

+0

謝謝,我編輯帖子重申我想說的內容 –