C++
給我們帶來了物件導向的支援,近年來在大型的嵌入式項目中經常被採用,甚至有一些較新的作業系統如eCos,Symbian等都採用C++編寫。不過C++在帶來一些便利的同時,也引入了很多昂貴的特性。隨著在嵌入式
開發領域使用
C++
作為開發語言的公司和項目越來越多,有不少原來工作在案頭開發領域的
C++
程式員加入了嵌入式
開發的陣營。對於這些由案頭開發轉入嵌入式
開發中的
C++
開發來說,需要特別注意程式的效率和資源佔用情況,瞭解哪些
C++
特性可能帶來執行時間和代碼大小上的昂貴開銷,並在有可能的情況下避免使用。
C++
中引入了類的概念,以利於對象的封裝,這在嵌入式
開發中是完全可以利用的,與
C
語言中的
struct
相比,類幾乎沒有多少更大的開銷。公有和私人成員資料及函數的列表與一個
struct
及函數原型的列表沒有大的差別。
C++
編譯器能夠用
public
和
private
關鍵字決定,哪一個方法調用和資料訪問是允許的或者是不允許的,但這個決定在編譯的時候完成,所以運行時不會付出代價。單純的加入類既不會影響代碼的大小,也不會影響你的程式的效率,而且還能夠有利於對象的封裝。
默
認參數值也是沒有損失的。編譯器只是加入代碼使得在每次函數被無參數調用的時候傳遞一個預設的值。類似地,函數名的重載也是編譯時間的修改。具有相同名字但
是不同參數的函數在編譯過程中分別分配了一個唯一的名字,每次函數名出現在程式中的時候編譯器就替換它,然後連接器正確的把它們匹配起來。這些都幾乎不會
帶來運行時的開銷,唯一的缺點是符號表稍微複雜一些。操作符的重載與此類似,幾乎沒有運行時的開銷。
構
造函數和解構函式會帶來一點損失。這些特殊的方法去分別保證每次這種類型的對象在建立或者超出了範圍時被調用。然而,這個小量的開銷是為減少錯誤而支付的
一個合理代價,是可以被接受的。類似的,虛擬函數也具有一個合理的代價收益比。它的明顯代價是在調用虛擬函數之前附加了一個儲存查詢,而普通的函數和方法
調用是不受影響的。由於它是實現多態的基礎,且代價比較小,是可以接受的。
根據一般的經驗,比較昂貴的
C++
特性有模板、例外狀況事件及運行類型識別
。這三個特性都對代碼的大小有負面的影響,而且例外狀況事件和運行時類型識別還會增加執行時間。在決定是否使用這些特性之前,你可能要做一些實驗來看看它們會怎麼樣影響你自己的應用程式的大小及速度。
事實上,在嵌入式
軟體界對於
C++
是否值得所產生的效能損失的問題一直存有很大的爭議。在
1996
年,一群日本的晶片廠商聯台起來定義了一個
C++
語言和庫的子集,使它更加適合嵌入式
軟體開發。他們把他們新的工業標準叫作嵌入式
C++
。作為一個
C++
標準草案的合適子集,嵌入式
C++
省略了很多不限制下層語言可表達性的任何可以省略的東西。這些被省略的特性不僅包括像多重繼承性、虛擬基類、運行時類型識別和異常處理等昂貴的特性,而且還包括了一些最新的添加特性,比如:模板、命名空問、新的類型轉換等。所剩下的是一個
C++
的簡單版本,它仍然是物件導向的並且是
C
的一個超集,但是它具有明顯更少的運行開銷和更小的運行庫。對嵌入式
C++
有興趣的讀者可以到這裡查看
Embedded C++
的詳細定義(
Specification
):
http://www.caravan.net/ec2plus/spec.html
。