几个月之前,接触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, ...) __printflike(2, 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, const char* const * items,
                           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, 0, sizeof(key_pressed));
}

现在看明白了。

写一个测试案例看看就懂了,果然一例解千愁啊!

#include <iostream>
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 b , 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

C++使用初始化列表的方式来初始化字段的更多相关文章

  1. const成员或者引用成员必须使用构造函数初始化列表的方式

    #include<iostream.h> class A { const int a; int b; }; void main() { A obja; }编译出现如下错误:error C2 ...

  2. C++:用成员初始化列表对数据成员初始化

    1.在声明类时,对数据成员的初始化工作一般在构造函数中用赋值语句进行. 例如: class Complex{ private: double real; double imag; public: Co ...

  3. 正确理解Widget::Widget(QWidget *parent) :QWidget(parent)这句话(初始化列表中无法直接初始化基类的数据成员,所以你需要在列表中指定基类的构造函数)

    最近有点忙,先发一篇我公众号的文章,以下是原文. /********原文********/ 最近很多学习Qt的小伙伴在我的微信公众号私信我,该如何理解下面段代码的第二行QWidget(parent) ...

  4. c++,初始化列表

    类对象的构造顺序是这样的: a.分配内存,调用构造函数时,隐式/显示的初始化各数据成员 b.进入构造函数后在构造函数中执行一般计算 1.初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内 ...

  5. c++构造函数成员初始化中赋值和初始化列表两种方式的区别

    先总结下: 由于类成员初始化总在构造函数执行之前 1)从必要性: a. 成员是类或结构,且构造函数带参数:成员初始化时无法调用缺省(无参)构造函数 b. 成员是常量或引用:成员无法赋值,只能被初始化 ...

  6. C++ 初始化列表(转)

    转载自:http://www.cnblogs.com/graphics/archive/2010/07/04/1770900.html 何谓初始化列表 与其他函数不同,构造函数除了有名字,参数列表和函 ...

  7. C++初始化列表(good)

    本文转载自http://www.cnblogs.com/graphics/archive/2010/07/04/1770900.html 感谢作者分享 何谓初始化列表 与其他函数不同,构造函数除了有名 ...

  8. C++构造函数初始化列表与构造函数中的赋值的区别

    C++类中成员变量的初始化有两种方式:构造函数初始化列表和构造函数体内赋值. 一.内部数据类型(char,int……指针等) class Animal { public: Animal(int wei ...

  9. C++的成员初始化列表和构造函数体(以前未知)

    成员的初始化列表和构造函数在对成员指定初值方面是不一样的.成员初始化列表是对成员初始化,而构造函数,是对成员赋值 成员初始化列表使用初始化的方式来为数据成员指定初值, 而构造函数的函数体是通过赋值的方 ...

随机推荐

  1. python2 跟3的区别

    1----python2:1 臃肿 , 源码的重复量很多2:语法不清晰,掺杂着 c,pyp,java,的一些陋习 python3: 几乎是重构后的源码,规范 清晰 优美 2.python的分类 分为编 ...

  2. ZOJ - 3593 One Person Game (扩展欧几里得)

    题意:一个人在坐标A,要前往坐标B的位置.可以往左或往右走a,b,a+b个单位,求到达B的最小步数. 分析:扩展欧几里得算法求解线性方程的套路不变.令C=fabs(A-B),c = a+b, 扩展gc ...

  3. 【Head First Servlets and JSP】笔记21:从有脚本到无脚本

    可以建立多态的bean引用吗 使用type,但没有class scope属性默认为“page” 从有脚本到无脚本 1.快速搭建一个测试环境:输入用户名,返回“Hello, 用户名” index.htm ...

  4. Samba 3.6.9 安装、管理

    Samba简介 Samba服务类似于windows上的共享功能,可以实现linux上共享文件,windows上访问,当然在linux上可以访问到.是一种在局域网上共享文件和打印机的一种通信协议,它为局 ...

  5. Nginx 静态缓存

    静态文件缓存 静态缓存在客户端下进行缓存,可以设置缓存文件类型与缓存时间,提升客户端访问站点速度. 主要对图片,css,js等元素更改机会比较少的情况下使用,特别是图片,占用带宽大,我们完全可以设置图 ...

  6. js算法-快速排序(Quicksort)

    快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),简称快排,一种排序算法,最早由东尼·霍尔提出.在平均状况下,排序n个项目要O(nLogn)次比 ...

  7. PHP面向对象程序设计之抽象类和抽象方法

    抽象类: 抽象类不能被实例化.抽象类中只定义(或部分实现)子类需要的方法.子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化. 我们可以用一个abstract关键字来定义一个抽象类,示例如下: ...

  8. .NET中如何测试Private和Protected方法

    TDD是1)写测试2)写通过这些测试的代码,3)然后重构的实践.在,NET社区中, 这个概念逐渐变得非常流行,这归功于它所增加的质量保证.此时,它很容易测试public方法,但是一个普遍的问题出现了, ...

  9. NUnit单元测试笔记

    vs2010 和 NUnit 问题处理. . 在 <configuration> 下 加 ... <startup> <requiredRuntime version=& ...

  10. spring boot项目获取application配置文件参数的两种方式

    前言:了解过spring boot这个技术的,应该知道spring boot的核心配置文件application.properties,当然也可以通过注解自定义配置文件**.properties的信息 ...