C++使用初始化列表的方式来初始化字段的方法
几个月之前,接触Android recovery源代码的时候,看ScreenRecoveryUI类的时候,那时候C++基础还不是特别好,一直不明白以下的初始化方式: 下面这个是Recovery的一个构造函数,代码位于:screen_ui.cpp,它的类的实现在screen_ui.h。 如下这个ScreenRecoveryUI类,这个类是继承于RecoveryUI类的: 这个文件在screen_ui.h class ScreenRecoveryUI : public RecoveryUI { public: ScreenRecoveryUI(); void Init(); void SetLocale(const char* locale); // overall recovery state ("background image") void SetBackground(Icon icon); // progress indicator void SetProgressType(ProgressType type); void ShowProgress(float portion,float seconds); void SetProgress(float fraction); void SetStage(int current,int max); // text log void ShowText(bool visible); bool IsTextVisible(); bool WasTextEverVisible(); // printing messages void Print(const char* fmt,...) __printflike(2,3); void ShowFile(const char* filename); // menu display void StartMenu(const char* const * headers,const char* const * items, int initial_selection); int SelectMenu(int sel); void EndMenu(); void KeyLongPress(int); void Redraw(); enum UIElement { HEADER,MENU,MENU_SEL_BG,MENU_SEL_BG_ACTIVE,MENU_SEL_FG,LOG,TEXT_FILL,INFO }; void SetColor(UIElement e); private: Icon currentIcon; int installingFrame; const char* locale; bool rtl_locale; pthread_mutex_t updateMutex; GRSurface* backgroundIcon[5]; GRSurface* backgroundText[5]; GRSurface** installation; GRSurface* progressBarEmpty; GRSurface* progressBarFill; GRSurface* stageMarkerEmpty; GRSurface* stageMarkerFill; ProgressType progressBarType; float progressScopeStart,progressScopeSize,progress; double progressScopeTime,progressScopeDuration; // true when both graphics pages are the same (except for the progress bar). bool pagesIdentical; size_t text_cols_,text_rows_; // Log text overlay,displayed when a magic key is pressed. char** text_; size_t text_col_,text_row_,text_top_; bool show_text; bool show_text_ever; // has show_text ever been true? char** menu_; const char* const* menu_headers_; bool show_menu; int menu_items,menu_sel; // An alternate text screen,swapped with 'text_' when we're viewing a log file. char** file_viewer_text_; pthread_t progress_thread_; int animation_fps; int installing_frames; int iconX,iconY; int stage,max_stage; void draw_background_locked(Icon icon); void draw_progress_locked(); void draw_screen_locked(); void update_screen_locked(); void update_progress_locked(); static void* ProgressThreadStartRoutine(void* data); void ProgressThreadLoop(); void ShowFile(FILE*); void PutChar(char); void ClearText(); void DrawHorizontalRule(int* y); void DrawTextLine(int* y,const char* line,bool bold); void DrawTextLines(int* y,const char* const* lines); void LoadBitmap(const char* filename,GRSurface** surface); void LoadBitmapArray(const char* filename,int* frames,GRSurface*** surface); void LoadLocalizedBitmap(const char* filename,GRSurface** surface); }; 下面是这个类的构造函数的实现,其中构造函数就采用了初始化列表的方式来初始化字段,以下构造函数的实现在screen_ui.cpp文件中可以找到。 ScreenRecoveryUI::ScreenRecoveryUI() : currentIcon(NONE), installingFrame(0), locale(nullptr), rtl_locale(false), progressBarType(EMPTY), progressScopeStart(0), progressScopeSize(0), progress(0), pagesIdentical(false), text_cols_(0), text_rows_(0), text_(nullptr), text_col_(0), text_row_(0), text_top_(0), show_text(false), show_text_ever(false), menu_(nullptr), show_menu(false), menu_items(0), menu_sel(0), file_viewer_text_(nullptr), animation_fps(20), installing_frames(-1), stage(-1), max_stage(-1) { for (int i = 0; i < 5; i++) { backgroundIcon[i] = nullptr; } pthread_mutex_init(&updateMutex,nullptr); } 可以来看看RecoveryUI类: 在ui.h中: class RecoveryUI { public: RecoveryUI(); virtual ~RecoveryUI() { } // Initialize the object; called before anything else. virtual void Init(); // Show a stage indicator. Call immediately after Init(). virtual void SetStage(int current,int max) = 0; // After calling Init(),you can tell the UI what locale it is operating in. virtual void SetLocale(const char* locale) = 0; // Set the overall recovery state ("background image"). enum Icon { NONE,INSTALLING_UPDATE,ERASING,NO_COMMAND,ERROR }; virtual void SetBackground(Icon icon) = 0; // --- progress indicator --- enum ProgressType { EMPTY,INDETERMINATE,DETERMINATE }; virtual void SetProgressType(ProgressType determinate) = 0; // Show a progress bar and define the scope of the next operation: // portion - fraction of the progress bar the next operation will use // seconds - expected time interval (progress bar moves at this minimum rate) virtual void ShowProgress(float portion,float seconds) = 0; // Set progress bar position (0.0 - 1.0 within the scope defined // by the last call to ShowProgress). virtual void SetProgress(float fraction) = 0; // --- text log --- virtual void ShowText(bool visible) = 0; virtual bool IsTextVisible() = 0; virtual bool WasTextEverVisible() = 0; // Write a message to the on-screen log (shown if the user has // toggled on the text display). virtual void Print(const char* fmt,3) = 0; virtual void ShowFile(const char* filename) = 0; // --- key handling --- // Wait for a key and return it. May return -1 after timeout. virtual int WaitKey(); virtual bool IsKeyPressed(int key); virtual bool IsLongPress(); // Returns true if you have the volume up/down and power trio typical // of phones and tablets,false otherwise. virtual bool HasThreeButtons(); // Erase any queued-up keys. virtual void FlushKeys(); // Called on each key press,even while operations are in progress. // Return value indicates whether an immediate operation should be // triggered (toggling the display,rebooting the device),or if // the key should be enqueued for use by the main thread. enum KeyAction { ENQUEUE,TOGGLE,REBOOT,IGNORE }; virtual KeyAction CheckKey(int key,bool is_long_press); // Called when a key is held down long enough to have been a // long-press (but before the key is released). This means that // if the key is eventually registered (released without any other // keys being pressed in the meantime),CheckKey will be called with // 'is_long_press' true. virtual void KeyLongPress(int key); // Normally in recovery there's a key sequence that triggers // immediate reboot of the device,regardless of what recovery is // doing (with the default CheckKey implementation,it's pressing // the power button 7 times in row). Call this to enable or // disable that feature. It is enabled by default. virtual void SetEnableReboot(bool enabled); // --- menu display --- // Display some header text followed by a menu of items,which appears // at the top of the screen (in place of any scrolling ui_print() // output,if necessary). virtual void StartMenu(const char* const * headers, int initial_selection) = 0; // Set the menu highlight to the given index,wrapping if necessary. // Returns the actual item selected. virtual int SelectMenu(int sel) = 0; // End menu mode,resetting the text overlay so that ui_print() // statements will be displayed. virtual void EndMenu() = 0; protected: void EnqueueKey(int key_code); private: // Key event input queue pthread_mutex_t key_queue_mutex; pthread_cond_t key_queue_cond; int key_queue[256],key_queue_len; char key_pressed[KEY_MAX + 1]; // under key_queue_mutex int key_last_down; // under key_queue_mutex bool key_long_press; // under key_queue_mutex int key_down_count; // under key_queue_mutex bool enable_reboot; // under key_queue_mutex int rel_sum; int consecutive_power_keys; int last_key; bool has_power_key; bool has_up_key; bool has_down_key; struct key_timer_t { RecoveryUI* ui; int key_code; int count; }; pthread_t input_thread_; void OnKeyDetected(int key_code); static int InputCallback(int fd,uint32_t epevents,void* data); int OnInputEvent(int fd,uint32_t epevents); void ProcessKey(int key_code,int updown); bool IsUsbConnected(); static void* time_key_helper(void* cookie); void time_key(int key_code,int count); }; ui.cpp中,也是采用字段初始化的方式来实现构造函数: RecoveryUI::RecoveryUI() : key_queue_len(0), key_last_down(-1), key_long_press(false), key_down_count(0), enable_reboot(true), consecutive_power_keys(0), last_key(-1), has_power_key(false), has_up_key(false), has_down_key(false) { pthread_mutex_init(&key_queue_mutex,nullptr); pthread_cond_init(&key_queue_cond,nullptr); memset(key_pressed,sizeof(key_pressed)); } 现在看明白了。 写一个测试案例看看就懂了,果然一例解千愁啊! #include using namespace std ; class ScreenRecoveryUI { private : int r,g,b ; char buffer[10] ; char *p ; public : ScreenRecoveryUI(); void setvalue(int a,int b,int c); void print(); }; //使用初始化列表的方式初始化构造函数里的私有环境变量 ScreenRecoveryUI::ScreenRecoveryUI(): r(0), g(0), b(0), p(nullptr){ for(int i = 0 ; i < 10 ; i++){ buffer[i] = 0 ; } } void ScreenRecoveryUI::setvalue(int a,int c) { this->r = a ; this->g = b ; this->b = c ; } void ScreenRecoveryUI::print() { cout << "r:" << this->r << endl << "g:" << this->g << endl << "b:" << b << endl ; } int main(void) { ScreenRecoveryUI screen ; screen.setvalue(255,255,0); screen.print(); return 0 ; } 运行结果: r:255 g:255 b:0 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对编程之家的支持。如果你想了解更多相关内容请查看下面相关链接 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |