2013-02-06 25 views
3

計劃沒有編制的原因很明顯:什麼0手段純虛函數如下

#include <iostream> 
using namespace std; 

class A { 
public: 
    A() { pVirt(); } 
    virtual void pVirt() const = 0 { count<<"A::pVirt()"; } 
}; 

int main() { 
A aObj; 
aObj.pVirt(); 
reutrn 0; 
} 

問題: 1.簽名0「虛擬無效pVirt()const的= 0」是什麼意思?是這表示在vtable中的NULL內存偏移量還是僅僅是一個語法約束?

  1. 如果0 NULL內存偏移(如果情況是這樣),那麼,爲什麼VC++不允許指定其他內存地址,這就是爲什麼我們不能從外部構造函數中調用純虛函數的原因(可能是因爲vtable是在完全構建完一個對象後創建的。)?

回答

4

這只是表示函數是純虛函數的語法。它沒有任何實際意義。 C++設計人員可以選擇使用pureabstract代替= 0。我懷疑不這樣做的唯一原因是他們不想在語言中引入新的保留字(因爲這會破壞已經使用新保留字作爲標識符的任何現有代碼)。

(這是沒有必要作出這樣的字保留,因爲這將是一個上下文敏感的關鍵字,但上下文敏感的關鍵詞的概念最近才進入主流應用,而這句法是老得多。)

+0

那麼在這裏阻止我們將其稱爲非純虛函數。 – null

+0

@ajay這與你的問題有什麼關係? '= 0'的存在阻止了你:C++只是指定任何具有純虛函數的類都不能被實例化。 –

+5

你忘了最重要的可能! '= 42;' –

4

0在簽名 「虛擬無效pVirt()const的= 0」 的意思?,

的部分=0稱爲純說明符。它使虛函數和類摘要

純虛函數不需要定義。你可能會可選提供一個類外的定義,而一個非抽象的派生類仍然必須覆蓋的功能。

class A 
{ 
public: 
    virtual ~A() {}; 
    virtual void f() =0; 
}; 

void A::f() { std::cout << "A::f" << std::endl; } //optional 

f定義不會使類非抽象的,所以你不能創建A實例:

A a; //error - A is abstract 

此外,派生類必須重寫A::f以是非 - 抽象:

class B : public A {}; 

B b; //error : B is still an abstract class as it didn't override A::f 

而且

class C : public A { void f() {} }; 

C c; //okay : C override A::f 

和派生類實現可以選擇調用基類的實現:

class D : public A { void f() { A::f(); } }; //defaults to A::f 

D d; //okay : D override A::f, but calls A::f internally 

希望有所幫助。

+1

你的答案是一個非常完整的解釋,它清除了純虛函數的可選聲明。謝謝! –

1

= 0之後的虛擬函數意味着「這是純虛函數,它必須在派生函數中實現」。就像在你的例子中一樣,它仍然可以實現這個功能。它沒有其他含義 - 你不能使用其他數字,地址或其他任何東西。你可以用=0有幾個函數,它仍然是相同的意思。

2

函數聲明中的= 0只是語法:兩個 令牌序列表示該函數是純的,就這樣。並且 您不能用任何其他方式替換任一令牌:例如,= 0L是不合法的。

而你得到錯誤的原因很簡單,因爲 語法是不允許的。由於歷史原因,如果沒有別的。 如果您想爲純虛擬功能提供定義,您必須在課程之外進行。

而且如果您爲純虛函數提供的定義, 可以從構造函數中調用它;你只需要 取消激活虛擬調用機制;例如A::pVirt()。如果 的實際函數調用涉及動態分辨率,並且分辨率導致純虛函數,則無論該函數是否定義,都不定義 行爲。 這裏的動機是讓你不要定義它;通常, 必須定義一個虛函數,無論你是否調用它, ,因爲編譯器必須把它的地址放在vtable, 如果沒有定義,就沒有地址。使虛函數 告訴編譯器它不應該將其 地址放入vtable。所以你不必定義它。但是 如果您嘗試通過 vtable調用該函數,您可能會感到驚訝。

+0

+1不錯的答案。剛剛重讀了Scott Meyers的舊的[專欄](http://www.artima.com/cppsource/nevercall.html)關於在構造函數中調用虛函數的複雜性:您指出我現在刪除的答案中的錯誤是正確的(didn不會爲你的答案提供附加價值)。 – TemplateRex