C# · 12月 20, 2021

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:" <r << endl << "g:" <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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接