程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> c構造函數

c構造函數

編輯:關於C語言

構造函數

  任何一們面向對象語言裡都會涉及構造函數這一概念,只是實現的方式各有差異。需要這main函數之前執行一段代碼是非常容易的事情,只需要聲明一對象的全局變量,在構造函數可以為所欲為干你想干的事情。然而,對於面向過程的語言比如C,需要實現全局的構造函數就比較奇葩。當然gcc會有很優雅的解決方式,VC則猥瑣點。

為何需要這個

  其實在main函數裡面調用一下就可以了,是的,這樣是可以,但是對於框架的實現來說,這卻是不太好的,客戶使用起來不自由。當然也可以說,我是屌絲,我可以裝逼點。

如何實現

  • gcc實現
    gcc 實現是非常簡單的事情。在全局構造函數前叫以下編譯器屬性即可:
    attribute((constructor))

  • vc實現
    vc的實現比較奇葩,VC本身沒有類似·attribute·這樣的屬性,你需要將全局函數編譯到某個特定的代碼段裡面。MSDN對於這部分有詳細的說明:CRT Initialization
    簡單來說就是將你的全局構造函數的函數指針編譯到·.CRT$XCU·段裡面。如何編譯到·.CRT$XCU·段?VC有VC的語法。

// 聲明在段·\.CRT$XCU·裡面生成代碼    
#pragma section("\.CRT$XCU",read)    
// 聲明需要調用的函數    
__declspec(allocate("\.CRT$XCU")) void (\_\_cdecl *a)(void) = func;    
// 調用的函數實現    
void func(void){}    

以上實現可以用下面實現:

#ifdef _MSC_VER    
#define __CCALL __cdecl    
#define __func__ __FUNCTION__    
#define snprintf _snprintf    
#pragma warning(disable:4996) // this is very violent    
#pragma section(".CRT$XCU",read)
#define __CONSTRCT(a, b)                                             \    
  void __CCALL __##a##__##b##__ ## 520hjm(void);                   \    
  __declspec(allocate(".CRT$XCU"))                                 \    
  void (__CCALL * __ctor__##a##__##b##__ ## 520hjm)(void) =        \    
  __##a##__##b##__ ## 520hjm;    
#else    
#define __CCALL    
#define __CONSTRCT(a, b) __attribute__((constructor))    

額外參考

仿照gtest的簡易單元測試ctest就是用的這方面的知識。

 

這裡顯示效果不是很好,個人網站那裡效果好點http://luoguochun.cn/2014/06/25/c-constructor/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved