1. 程式人生 > >c++建構函式成員變數的初始化

c++建構函式成員變數的初始化

前言

寫程式碼的時候才發現自己有多麼菜,昨天應為建構函式變數初始化理解錯誤導致了未初始化的錯誤。

前因後果

看看我怎麼定義的,

typedef struct rb_node{
        int key;
        int bhight;
        int color;
        struct rb_node* left;
        struct rb_node* right;
        struct rb_node* parent;
        rb_node(int key, int color = 1, int bhight = 0,
                        struct
rb_node* left = NULL, struct rb_node* right = NULL, struct rb_node* parent = NULL):key(key),color(color){ } //...省略無關緊要的 } RBnode,*PRBnode;

自以為,在函式的變數名和成員函式的變數名寫的一樣,還定義了預設值,它就能自動賦值。卻忘記了函式本來的定義規則。這樣寫的話,除了key和color會被賦值其他的都不會被初始化。導致了後面的 left right變成了野指標,訪問時出現了段錯誤。

然後我又犯了另外一個錯誤,

rb_node(int key, int color = 1, int bhight = 0,
    struct rb_node* left = NULL, struct rb_node* right = NULL,
    struct rb_node* parent = NULL):key(key),color(color) {
    right = right; // 錯誤1  
    left = NULL;   // 錯誤2           
}
  • 錯誤 1:
    以下是對right = right這個錯誤的回答,在linux g++測試的,不用this 類中的right是不會被賦值為right(NUL的。
引數名可以和成員變數名相同嗎?
視訊裡在給有參構造變數指定引數的時候,老師講為了便於我們把引數名和成員變數名區分開,所以在引數名前面加new,那麼引數名可以和成員變數名相同嗎?
public Telphone(float screen,float cpu,float mem){
screen=screen;
cpu=cpu;
mem=mem;
}
這樣可以嗎?

可以 但是必須要用this來區分 
public Telphone(float screen,float cpu,float mem){
this.screen=screen;
this.cpu=cpu;
this.mem=mem;
}
  • 錯誤2:
    left = NULL 這樣類中的left 也不會被賦值。

  • 錯誤3:
    對初始化列表中成員變數的賦值的順序理解也不準確。賦值的順序指的是冒號後的這一塊 :key(key),color(color) ,是先執行key的還是先執行color,就要看,key和color定義的順序了,對於引數有依賴關係的就要注意一下順序。

所以正確的寫法:

rb_node(int key, int color = 1, int bhight = 0,
        struct rb_node* left = NULL, struct rb_node* right = NULL,
        struct rb_node* parent = NULL):key(key),color(color),bhight(bhight){
        this->right = right;  //當然這一部分都可以放在初始化列表後  
        this->left = left;
        thi->parent = parent;              
}

結論

在類中,最好使用this,還有引數名和成員變數名最好不一樣,還有我這麼菜就是因為寫的太少,都是在看程式碼,沒有寫,不能知道里面的坑。