題:
Arduino的OOP與內聯
Andy Braham
2015-11-21 01:32:38 UTC
view on stackexchange narkive permalink

我已經編程了一段時間了,但是我是Arduino和AVR編程的新手。我對這些微控制器進行編程的主要問題是,在面向對象的類中設計代碼與在許多示例中看​​到的更傳統的嵌入式編程之間是否存在重大差異?

換句話說,在Arduino / AVR控制器世界中,利用類或反之亦然可以在內存和性能方面節省任何費用嗎?

例如說我們有一個類:

  class SomeClass(){private:int x; int y; public:void foo(); void bar();} SomeClass thisClass; thisClass.foo(); thisClass.bar();  

以更加內聯的方式設計程序是否會帶來任何性能或內存方面的收益,例如:

  int x; int y; void foo(){/ ***做某事*** /}; void bar(){/ ***做更多事*** /} ;  

我嘗試在Stack Exchange和Google上進行一些搜索,但找不到完全答案,我在尋找能夠找到的最接近的東西是這個Stack Exchange問題

我之所以要問這個問題,是因為我有一個項目,它需要盡可能輕巧,而且我不清楚在這種環境下如何設計程序。 p>


編輯

感謝您的回答,這為您提供了幫助。我不太清楚一件事。

假設您正在設計一個使用u8glib的類,如下所示:

  class UserInterface {private:U8GLIB_ST7920_128X64 Display; public:UserInterface();} 代碼> 

如何使用“動態內存”,如:

  UserInterface :: UserInterface(){UserInterface :: Display = U8GLIB_ST7920_128X64(LCD_E_PIN,LCD_RW_PIN,LCD_RS_PIN ,U8G_PIN_NONE);}  
二 答案:
Majenko
2015-11-21 01:56:23 UTC
view on stackexchange narkive permalink

找不到答案的原因是因為答案都是肯定和否。

對於基本類的東西-使用方法等定義類並從中實例化對象-幾乎沒有區別與“原始” C相比,最終結果。編譯器的優化是如此出色,以至於性能完全相同。是的,由於每次方法調用都要傳遞一個額外的指針(而不是 foo(int x)而是 foo(MyClass * this,int x )),但它是如此之小以至於不被注意到。

當您開始玩 polymorphism 和其他高級主題時,會有很大的不同。開始編寫這些複雜程序時,編譯器並非總是無法確定哪些功能是必需的,哪些不是必需的,並且它也無法切出未使用的功能(“垃圾收集” )。因此,您可能最終會得到更大的代碼。

這並不意味著速度較慢的代碼,只是周圍徘徊著的代碼塊什麼也做不到。

更重要的是管理動態記憶比以前更好。由於內存量非常小,因此堆非常小,因此很容易將其碎片化。動態創建和銷毀對象( new myClass delete myClassObject 等)非常糟糕。類對象確實需要靜態定義(在全局範圍內是最常見的)或臨時分配在堆棧上(本地實例)。否則,您會自找麻煩-首先您會知道這是一件奇怪的事情(沒有錯誤報告或異常,您會看到...)。

好吧,如果我在當今的編程世界中正確理解了這一點,那麼類將被用作組織和可移植性的角色,而不是真正的OOP,並且應該靜態地,顯式地而不是動態地分配事物。非常感謝,這很有道理,並解釋了為什麼我一直看到示例,以及為什麼沒有寫成示例。
Mikael Patel
2015-12-01 03:37:19 UTC
view on stackexchange narkive permalink

我對這些微控制器進行編程的主要問題是,在面向對象的類中設計代碼與在許多示例中看​​到的更傳統的嵌入式編程之間是否存在重大差異?

...

換句話說,在Arduino / AVR控制器世界中,使用類或反之亦然,內存和性能方面有什麼節省嗎?用於小型嵌入式系統(例如Arduino / AVR)的C或C ++。 C ++允許為編譯器優化提供更多信息。

如果要實現OOP框架,平台或運行時C ++和類也可以幫助軟件體系結構和重用。在 Cosa中,許多OOP設計模式用於為應用程序程序員和設備驅動程序程序員實現接口。最常見的是代理

使用抽像類,虛擬成員函數,內聯和模板可以幫助實現比傳統實現更低的佔用空間和更高的性能。例如,Cosa Pin類的速度比Arduino內核快X5-X10,同時佔用空間更小。請參閱基準

從傳統C ++編程中“學習”的一件事是使用new / delete(malloc / free)。使用堆只有幾KB的SRAM大小是非常危險的。答案是靜態類和基於堆棧的數據。

關於OOP框架體系結構還有很多要說的,但我希望這可以回答您的最初問題。

乾杯!

好答案!我更新了我的問題,詢問如何解決動態內存(新/刪除/ malloc /免費)。您是否有關於不使用動態內存分配的信息?是否需要在整個課程中共享的所有內容都是全球性的?這聽起來不對,我總是被教導不要使用全局變量(如果可以幫助的話)。
對上面的UserInterface示例的簡短評論。 Display實際上是對象組合(不是參考/指針),因此您不需要新的對象。您確實需要啟動顯示器。 UserInterface構造應如下所示。 `UserInterface :: UserInterface():顯示(LCD_E_PIN,LCD_RW_PIN,LCD_RS_PIN,U8G_PIN_NONE){...}`。必需的Display構造函數參數應傳遞給UserInterface構造函數。
OOP完全是關於封裝,隱藏數據的,因此共享應為最小值(零)。目標是或多或少僅具有多個相互作用的全局靜態對象。他們持有並隱藏了全球狀態。對於對象,成員數據是非動態本地狀態。為了實現這一目標,您還需要一系列技巧。程序轉換。
一個例子;考慮可能具有可變數量的成員的BitSet類的設計。顯而易見的解決方案是計算所需的字節數並使用new / malloc。另一種選擇是將存儲作為參數傳遞給BitSet構造函數。第三種選擇是使用元素數量作為參數的模板類。這允許一個成員變量為必需的字節數。請參閱[Cosa / BitSet.hh](https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/BitSet.hh),以獲取有關此程序轉換變體的更多詳細信息。還有更多的轉變。
我更新了UserInterface示例,這或多或少是正確的方法?我想我現在對如何實現所需的功能已經有了很好的理解。
Cosa庫聽起來像它包含了我要查詢的許多功能。我去了網站,發現它完全替代了Arduino庫。 Cosa的開銷和占用空間可與Arduino庫媲美嗎?
Cosa(根據基準)具有更高的性能和更低的內存佔用。例如,Cosa Pin類的速度比Arduino / Wiring功能快X5-X10,Cosa UART(串行)可以以高達2Mbps的速度運行和100%的帶寬,以高達1Mbps的速度運行。它支持事件,定時/排隊函數(作業),fsm,原型線程,線程等。但是最重要的問題是類被設計為可以協同工作。
您的更新不正確。顯示不應是靜態的。
我再次更新了我的問題,我當時認為Display應該是靜態的,因為我只希望一個實例在內存中,因為實際上只有一個Display。


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...