2017-03-07 42 views
0

參考此問題,How to resolve "pure virtual method called"是否存在編譯器選項,當從構造函數/析構函數調用虛方法時會引發錯誤?當存在純粹的虛擬方法時,程序將在運行時出現分段錯誤。編譯器選項禁止從構造函數調用純虛方法

這是多次證明是一個糟糕的設計:

當你從你的構造函數/析構函數中調用虛擬方法

這不是他們的被覆蓋的版本被稱爲

編輯:

我特別要求MSVC,但如果每個編譯器(GCC,CLANG等)都有一個選項,它會很有用。

+0

具體哪個編譯器? –

+0

我添加了這個信息。 –

+1

「這已被多次證明是不好的設計」,是的,直接明確地調用UB是糟糕的設計。但是你的報價不支持。所以整個段落都是壞邏輯。 –

回答

3

是否有一個編譯器選項在從構造函數/析構函數調用虛擬方法時引發錯誤?當存在純粹的虛擬方法時,程序將在運行時出現分段錯誤。

但是如果每個編譯器有一個選項(GCC,CLANG等),它會很有用。

對於GCC和Clang,選項是-Werror。這將導致所有警告提示錯誤。如果您直接在構造函數或析構函數中調用純虛函數,則兩個編譯器默認都會發出警告。

如果調用非純虛函數,當然沒有警告/錯誤。它有明確的行爲。另外,編譯器通常不能檢測對純虛函數的間接調用。

我不知道MSVC。

這是多次證明是一個糟糕的設計:

如果你指的是C-/ d-TOR幾乎調用一個純虛函數,然後糟糕的設計是輕描淡寫。行爲是未定義的。如果你不走運,程序甚至可能不會崩潰。

+0

@ Cheersandhth.-Alf關於你的編輯:是否甚至有可能在c-/d-tor中調用一個函數?據我所知,這個調用總是非虛擬的,這就是爲什麼它是錯誤的,因爲純虛函數可能甚至沒有定義。 – user2079303

+0

是的,虛擬函數的非限定調用總是*虛擬的。然而,在類T的構造函數中,**動態類型**是T.並且這意味着虛擬呼叫,例如從基類函數中,最多可以歸結爲T對相關函數的實現。 –

+0

我已經發布了一個[關於這方面的問題,讓我有疑問](http://stackoverflow.com/questions/42645853/calling-class-ts-implementation-of-pure-virtual-from-t-構造函數沒有-QUAL)。可能是由於缺乏咖啡 - 我喝不完咖啡了!但仍然。 –

0

我還沒有發現在Visual Studio中這方面的任何編譯器開關,但在Visual Studio中運行時的處理程序進行的:_purecall,它坐落在運行時文件PureVirt.c。每當虛擬函數的vtable中沒有條目時,就會調用它,當你有一個純虛擬調用時就是這種情況。

可以重載此功能,並添加的DebugBreak

但這只是一種變通方法來獲取調用堆棧爲您的純虛擬呼叫。