C++ warning:’xxx‘ has no out-of-line virtual method definitions...
前言
最近在復習一些 C++基礎知識,寫了一些 C++的代碼,當我在類中定義了虛函數并且直接在類定義內部實現這些虛函數時,編譯器就會報警告:’xxx‘ has no out-of-line virtual method definitions;its vtable will be emitted in every translation unit.
如下圖:
如何解決
以前好像從來沒留意過這些問題,然后決定找找原因,后來查了一些資料終于找到真正的原因,來看一段話:
If a class is defined in a header file and has a vtable (either it has virtual methods or it derives from classes with virtual methods), it must always have at least one out-of-line virtual method in the class. Without this, the compiler will copy the vtable and RTTI into every .o file that #includes the header, bloating .o file sizes and increasing link times
這里大概意思就是:
如果在頭文件中定義了一個類并且具有vtable(它具有虛方法或者它來自具有虛方法的類),則它必須始終在類中具有至少一個外聯虛擬方法。 如果沒有這個,編譯器會將vtable和RTTI復制到每個.o文件中,其中#include標題,膨脹.o文件大小和增加鏈接時間。
也就是說,當類中定義了虛函數時,編譯器會自動生成虛函數表vtable,用來對應每一個虛函數。那么,如果所有虛擬方法都是內聯的(在頭文件中定義),那么編譯器不知道哪個翻譯單元(.cpp文件)在其中發出vtable,因此它會在所有這些中發出一個副本,并且鏈接器會處理用它。這會在目標文件中產生額外的工作和并且是.o文件變得更龐大。另一方面,如果虛擬函數是在線外定義的(在.cpp中),則可以在那里發射vtable,因此只會發出一個副本。
所以知道以上原因過后,解決方法就很簡單了,因為我是在類中定義了虛函數并且直接在類定義內部實現這些虛函數,所以將虛函數自動變成了內聯函數,那么只需要把虛函數的實現挪到類的外面去實現就可以啦。
反思
1.本是一個習慣性的操作,有時候覺得定義的函數實現比較簡單,所以就直接在類定義中實現,這就自動變成了內聯函數,但是沒想過不同的函數類型可能會帶來不同的影響。
2.不要忽視編譯器警告。通常我們在寫代碼,只要沒出錯就覺得萬事大吉了,很少會去留意警告信息,但是其實警告信息也非常重要,因為它可能會成為今后軟件出問題的一個導火線。
3.知其然,知其所以然。了解一些編譯器的工作原理可以更有助于去改善代碼質量。之前在看《深度探索C++對象模型》時深有感觸。
總結
以上是生活随笔為你收集整理的C++ warning:’xxx‘ has no out-of-line virtual method definitions...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++设计模式--模板方法模式
- 下一篇: C++之 RTTI