《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計應(yīng)用 > 用C語言實現(xiàn)類實例化的研究
用C語言實現(xiàn)類實例化的研究
2016年微型機與應(yīng)用第23期
楊韜
廣州致遠電子股份有限公司,廣東 廣州 510660
摘要: 多年以來,C語言在嵌入式軟件開發(fā)中被廣泛使用,但由于開發(fā)人員和應(yīng)用場景等原因,面向?qū)ο?、設(shè)計模式等優(yōu)秀的軟件開發(fā)方法始終沒有很好地運用起來。時至今日,物聯(lián)網(wǎng)等應(yīng)用的興起,給嵌入式軟件開發(fā)帶來新的挑戰(zhàn),而傳統(tǒng)的面向過程開發(fā)已經(jīng)難以支撐這些復(fù)雜的應(yīng)用。因此,有必要在嵌入式軟件開發(fā)中引入面向?qū)ο蟆⒃O(shè)計模式等優(yōu)秀的軟件開發(fā)方法。面向?qū)ο笫乾F(xiàn)代軟件方法的根基,面向?qū)ο篌w現(xiàn)在類上,使用類來創(chuàng)建對象的過程就是實例化。文章結(jié)合C語言的特性,對使用C語言實現(xiàn)類實例化進行了討論。
Abstract:
Key words :

  楊韜

  (廣州致遠電子股份有限公司,廣東 廣州 510660)

       摘要:多年以來,C語言在嵌入式軟件開發(fā)中被廣泛使用,但由于開發(fā)人員和應(yīng)用場景等原因,面向?qū)ο?/a>、設(shè)計模式等優(yōu)秀的軟件開發(fā)方法始終沒有很好地運用起來。時至今日,物聯(lián)網(wǎng)等應(yīng)用的興起,給嵌入式軟件開發(fā)帶來新的挑戰(zhàn),而傳統(tǒng)的面向過程開發(fā)已經(jīng)難以支撐這些復(fù)雜的應(yīng)用。因此,有必要在嵌入式軟件開發(fā)中引入面向?qū)ο?、設(shè)計模式等優(yōu)秀的軟件開發(fā)方法。面向?qū)ο笫乾F(xiàn)代軟件方法的根基,面向?qū)ο篌w現(xiàn)在上,使用類來創(chuàng)建對象的過程就是實例化。文章結(jié)合C語言的特性,對使用C語言實現(xiàn)類實例化進行了討論。

  關(guān)鍵詞: C語言;面向?qū)ο?;類;實例?/p>

  中圖分類號:TP312文獻標識碼:ADOI:10.19358/j.issn.16747720.2016.23.004

  引用格式:楊韜. 用C語言實現(xiàn)類實例化的研究[J].微型機與應(yīng)用,2016,35(23):15-17.

0引言

  物聯(lián)網(wǎng)等應(yīng)用的興起,給嵌入式軟件開發(fā)帶來新的挑戰(zhàn),而傳統(tǒng)的面向過程開發(fā)已經(jīng)難以支撐這些復(fù)雜的應(yīng)用。因此,有必要在嵌入式軟件開發(fā)中引入面向?qū)ο蟆⒃O(shè)計模式等優(yōu)秀的軟件開發(fā)方法。本文討論了如何使用C語言來實現(xiàn)類的實例化。在C++等面向?qū)ο笳Z言中對類做了原生的支持,使用new這類關(guān)鍵字即可實例化一個對象。盡管C語言并不支持new,但是通過對實例化過程的分析和拆分,也能實現(xiàn)實例化。

1基本概念[1]

  1.1類

  面向?qū)ο笥蟹庋b、繼承、多態(tài)三大特性,這些特性主要通過類來體現(xiàn)。類就是一個封裝了屬性以及相關(guān)操作的代碼的邏輯實體。

  類具有屬性,它是對象的狀態(tài)的抽象,用數(shù)據(jù)結(jié)構(gòu)來描述類的屬性。

  類具有方法,它是對象的行為的抽象,用方法名和實現(xiàn)該操作的方法來描述。

  除了封裝屬性和操作外,類還具有訪問控制的能力,比如,某些屬性和方法可以是私有的,不能被外界訪問。通過訪問控制,能夠?qū)?nèi)部數(shù)據(jù)提供不同級別的保護,以防止外界意外地改變或使用了私有部分。不同的編程語言提供的訪問控制等級不盡相同,但都有公有、私有兩個等級。

  類是抽象的數(shù)據(jù)類型,在內(nèi)存中并不存在(Python等動態(tài)語言除外),只有類的實例存在于內(nèi)存中。

  1.2對象

  對象是人們要進行研究的任何事物,從最簡單的整數(shù)到復(fù)雜的飛機等均可看作為對象,它不僅能表示具體的事物,還能表示抽象的規(guī)則、計劃或事件。

  對象具有狀態(tài),一個對象用數(shù)據(jù)值來描述它的狀態(tài)。

  對象還有操作,用于改變對象的狀態(tài),對象及其操作就是對象的行為。

  對象實現(xiàn)了數(shù)據(jù)和操作的結(jié)合,使數(shù)據(jù)和操作封裝于對象的統(tǒng)一體中。

  1.3實例化

  用類創(chuàng)建對象的過程就是實例化,創(chuàng)建的對象被稱為類的實例。實例化包含兩個步驟,第一步是分配對象的內(nèi)存,第二步是初始化對象的內(nèi)存。

2類封裝的C語言實現(xiàn)

  類的第一大特性為封裝,封裝即將對象的屬性和方法封裝在一起,在C語言中可以使用.C、.H和結(jié)構(gòu)體實現(xiàn)類的封裝特性。

  以圖1中Human類為例,可以使用human.h、human.c、struct human三個元素來完成封裝,human.c為human.h中函數(shù)聲明的實現(xiàn),本文不討論這些細節(jié),所以只給出如下human.h的關(guān)鍵代碼片段:

圖像 001.png

  typedef struct human {

  const char *name;

  int_money;

  } human_t;

  human_t *human_init (human_t *p_this, const char *name, int money);

  voidhuman_talk (human_t *p_this, const char *p_words);

  voidhuman_buy (human_t *p_this, const char *p_something, unsigned price, unsigned count);

  voidhuman_deinit (human_t *p_this);

3類實例化的C語言實現(xiàn)

  實例化包含兩個步驟:分配對象的內(nèi)存和初始化對象的內(nèi)存。接下來本文以圖1中Human類的實例化為例,討論C語言如何實現(xiàn)類的實例化。

  3.1對象的內(nèi)存

  如果把類看做類型,那么類的實例就是變量,既然是變量,那么就有動態(tài)變量、靜態(tài)變量和棧變量之分。在C語言中,使用malloc()這類動態(tài)內(nèi)存分配函數(shù)得到的變量就是動態(tài)變量;全局變量和加了static關(guān)鍵字的變量就是靜態(tài)變量;在函數(shù)內(nèi)創(chuàng)建的局部變量就是棧變量。下面的代碼展示了C語言中的這幾類變量:

  #include "human.h"

  struct humang_john;/* 靜態(tài)變量 */

  static struct human __g_john;/* 靜態(tài)變量 */

  void foo (void)

  {

  static struct human s_john;/* 靜態(tài)變量 */

  struct human john;/* 棧變量 */

  struct human*p_john = malloc(sizeof(*p_john));

  /* 動態(tài)變量 */

  }

  站在內(nèi)存的角度,可以把類看做結(jié)構(gòu)體類型,類的實例就是結(jié)構(gòu)體變量,因此,對象也就有動態(tài)對象、靜態(tài)對象和棧對象之分,它們之間的區(qū)別如表1所示。

圖像 002.png

  free()

  釋放內(nèi)存內(nèi)存分配可能失敗,花費的時間可能不確定;需要處理內(nèi)存分配失敗的情況,增加程序的復(fù)雜性可以在需要時創(chuàng)建和銷毀對象靜態(tài)對象位于.data、

  .bss內(nèi)存段需要編譯時確定對象的數(shù)量;一直占用內(nèi)存;對象數(shù)量太多太大時會影響程序啟動時間確定性好,只要程序能夠運行起來,就一定能夠創(chuàng)建成功棧對象位于系統(tǒng)

  棧、對象棧對象太大會導(dǎo)致棧溢出自動完成對象內(nèi)存的分配和回收

  對于嵌入式軟件中的C面向?qū)ο缶幊?,充分理解?中的這三類對象是非常有必要的。大多數(shù)情況下,一個類都要能夠被實例化為靜態(tài)對象。

  3.2對象的初始化

  初始化對象就是初始化對象的內(nèi)存,在初始化之前,必然要先得到對象的內(nèi)存(上一小節(jié)已討論),但無論對象的內(nèi)存是何種類型,初始化的操作都是相同的。在JAVA等編程語言中,完成此操作的函數(shù)被稱作構(gòu)造函數(shù),使用C語言來實現(xiàn)就是一個名為xxxx_init()的初始化函數(shù),也可稱之為構(gòu)造函數(shù)。

  以Human類為例,它的初始化函數(shù)human_init()如下面的代碼所示,可留意到對象的內(nèi)存需要顯式傳遞給它。

  human_t *human_init (human_t *p_this, const char *name, int money)

  {

  p_this->name = name;

  p_this->_money = money;

  return p_this;

  }

  3.3實例化

  前面兩小節(jié)分別討論了對象的內(nèi)存和對象的初始化,這兩步組成了實例化。下面的代碼展示了不同類型對象的實例化:

  #include "human.h"

  human_tg_john;/* 靜態(tài)對象 */

  statichuman_t__g_jen;/* 靜態(tài)對象 */

  void foo (void)

  {

  static human_ts_jack;/* 靜態(tài)對象 */

  human_t tom;/* 棧對象 */

  human_t*p_lee_mem= malloc(sizeof(*p_lee_mem));

  /* 動態(tài)對象 */

  // 實例化上面定義的靜態(tài)對象、動態(tài)對象和棧對象

  human_t *p_john= human_init(&g_john, "john", 100);

  human_t *p_jen = human_init(&__g_jen, "jen", 100);

  human_t *p_jack = human_init(&s_jack, "jack", 100);

  human_t *p_tom = human_init(&tom, "tom", 100);

  human_t *p_lee = human_init(p_lee_mem, "lee", 100);

  3.4訪問對象

  對象實例化后便存于內(nèi)存中,此時可以訪問對象的屬性和方法,下面的代碼展示了對象的訪問:

  #include "human.h"

  void foo (void)

  {

  human_t john;/* 定義對象內(nèi)存 */

  p_john = human_init(&jhon, "John", 100);

  /* 初始化對象 */

  printf("Human %s is born!", p_john->name);

  /* 訪問對象的屬性 */

  human_talk(p_john, "I am hungry");

  /* 訪問對象的方法 */

  human_deinit(&john)/* 對象解初始化 */

  }

  3.5銷毀對象

  當對象不再使用時,便可銷毀之。銷毀對象與創(chuàng)建對象(實例化)的操作相反,首先對對象進行解初始化操作,然后再釋放對象的內(nèi)存。

  以Human類為例,首先調(diào)用human_deinit()完成對象的解初始化,接下來,如果是靜態(tài)對象或棧對象就不用顯式釋放對象的內(nèi)存,因為靜態(tài)對象或棧對象有確定的生命周期;如果是調(diào)用malloc()等函數(shù)得到了動態(tài)對象,則必須調(diào)用free()等對應(yīng)的函數(shù)釋放對象的內(nèi)存。下面的代碼展示了各種對象的銷毀:

  #include "human.h"

  human_tg_john;/* 靜態(tài)對象 */

  statichuman_t__g_jen;/* 靜態(tài)對象 */

  void foo (void)

  {

  static human_ts_jack;/* 靜態(tài)對象 */

  human_t tom;/* 棧對象 */

  human_t*p_lee_mem= malloc(sizeof(*p_lee_mem));

  /* 動態(tài)對象 */

  // 實例化上面定義的靜態(tài)對象、動態(tài)對象和棧對象

  human_t *p_john = human_init(&g_john, "john", 100);

  human_t *p_jen = human_init(&__g_jen, "jen", 100);

  human_t *p_jack = human_init(&s_jack, "jack", 100);

  human_t *p_tom = human_init(&tom, "tom", 100);

  human_t *p_lee = human_init(p_lee_mem, "lee", 100);

  /* 銷毀對象 */

  human_deinit(p_john);

  human_deinit(p_jen);

  human_deinit(p_jack);

  human_deinit(p_tom);

  human_deinit(p_lee);

  free(p_lee_mem);

  /* 注意:需要用戶釋放動態(tài)申請的對象內(nèi)存 */

  }

4結(jié)論

  本文通過使用C語言實現(xiàn)Human類的實例化,討論了如何使用C語言來實現(xiàn)類的實例化。在C++等面向?qū)ο笳Z言中對類做了原生的支持,使用new這類關(guān)鍵字即可實例化一個對象。盡管C語言并不支持new,但是通過對實例化過程的分析和拆分,也能實現(xiàn)實例化。

  參考文獻

 ?。?] 百度. 百度百科/面向?qū)ο螅跡B/OL].(2016-08-08).http://baike.baidu.com/link?url=6XlXEOSlrKn87S7SJv4 UWSX7EjstoDVm wJ13OAod XUrUrnZkVg3ntPFir Ey5c6mqOb ZZOevQI6K3Ungq1Mq.



此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。