C 成員變數 建構函式的初始化順序

2021-09-06 14:38:03 字數 3009 閱讀 8922

一、c++成員變數初始化

1、普通的變數:一般不考慮啥效率的情況下 可以在建構函式中進行賦值。考慮一下效率的可以再建構函式的初始化列表中進行

2、static 靜態變數(本地化資料和**範圍):

static變數屬於類所有,而不屬於類的物件,因此不管類被例項化了多少個物件,該變數都只有乙個。在這種性質上理解,有點類似於全域性變數的唯一性。

3、const 常量變數:

const常量需要在宣告的時候即初始化。因此需要在變數建立的時候進行初始化。一般採用在建構函式的初始化列表中進行。

4、reference 引用型變數:

引用型變數和const變數類似。需要在建立的時候即進行初始化。也是在初始化列表中進行。但需要注意用reference型別。

4、字串初始化

char str[10] = "hello";

結尾會被編譯器自動加上結尾符'/0',編譯的時候可以看到它最後是'',asc碼值是0;

"hello"只有5個字元,加上編譯器自動新增的'/0',也就是會初始化陣列的前6個元素,剩下有元素會被全部初始化為'/0',這個要注意哦

char str = "hello";

編譯器自動為後面的字串分配大小並加'/0'

char str = ;

編譯器會根據字串大小分配空間,可是不會自動分配'/0',所以結尾的時候要自己加上'/0'

char *str = "hello";

把指向字串的指標給定義好的字元指標

1)用建構函式確保初始化

對於乙個空類,編譯器會自動宣告4個預設函式:建構函式、拷貝建構函式、賦值函式、析構函式(如果不想使用自動生成,就應該明確拒絕),這些生成的函式都是public且inline的。

2)為什麼建構函式不能有返回值

3)為什麼建構函式不能為虛函式

虛函式呼叫的機制,是知道介面而不知道其準確物件型別的函式,但是建立乙個物件,必須知道物件的準確型別;當乙個建構函式被呼叫時,它做的首要事情之一就是初始化它的vptr來指向vtable。

面試題:建構函式

#include

using namespace std;

class base

};class derived : public base

void print()

};int main()

首先,是訪問許可權問題,子類中直接訪問base::i是不允許的,應該將父類的改為protected或者public(最好用protected)

其次,統計父類和子類i的和,但是通過子類建構函式沒有對父類變數進行初始化;此處編譯會找不到建構函式,因為子類呼叫建構函式會先找父類建構函式,但是沒有2個引數的,所以可以在初始化列表中呼叫父類建構函式

最後個問題,是單引數的建構函式,可能存在隱式轉換的問題,因為單引數建構函式,和拷貝建構函式形式類似,呼叫時很可能會發生隱式轉換,應加上explicit關鍵字

#include

using namespace std;

class base

};class derived : public base

void print()

};int main()

2、初始化列表

1)使用初始化列表提高效率

class student

private :

string name;

int age;

};因為在建構函式中,是對name進行賦值,不是初始化,而string物件會先呼叫它的預設建構函式,再呼叫string類(貌似是basic_string類)的賦值建構函式;對於上例的age,因為int是內建型別,應該是賦值的時候獲得了初值。

要對成員進行初始化,而不是賦值,可以採用初始化列表(member initialization list)

class student

private :

string name;

int age;

};在初始化的時候呼叫的是string的拷貝建構函式,而上例會呼叫兩次建構函式,從效能上會有不小提公升

有的情況下,是必須使用初始化列表進行初始化的:const物件、引用物件

2)初始化列表初始順序

#include

using namespace std;

class base

base() : m_j(0), m_i(m_j) {}

int get_i() const

int get_j() const

private:

int m_i;

int m_j;

int main()

輸出為乙個隨機數和98,為什麼呢?因為對於初始化列表而言,對成員變數的初始化,是嚴格按照宣告次序,而不是在初始化列表中的順序進行初始化,如果改為賦值初始化則不會出現這個問題,當然,為了使用初始化列表,還是嚴格注意宣告順序吧,比如先宣告陣列大小,再宣告陣列這樣。

c++建構函式初始化按下列順序被呼叫:

#include

using namespace std;

class obj1

};class obj2

}class base1

}class base2

};class base3

};class base4

};class derived :public base1, virtual public base2,public base3, virtual public base4//繼承順序

protected:

obj1 obj1;//宣告順序

obj2 obj2;

};int main()

結果:base2 //虛擬基類按照被繼承順序初始化

base4 //虛擬基類按照被繼承的順序

base1 //非虛擬基類按照被繼承的順序初始化

base3 //非虛擬基類按照被繼承的順序

obj1 //成員函式按照宣告的順序初始化

obj2 //成員函式按照宣告的順序

derived ok.

this is ok.

建構函式初始化列表初始化成員變數的順序

include include include using namespace std class point point point point p intgetx intgety intmain 執行結果如下 可以看到m x m y按照我們預想的結果進行了初始化,輸出結果符合預期。接下來我們將私...

C 建構函式初始化變數的順序

在 c 中類的建構函式初始值列表 中提到,c 中類的建構函式初始值列表可以對類的成員進行初始化。但是需要注意的是,建構函式的初始化列表只是說明各變數的初始值,並沒有指定變數的初始化順序。其中,myclass類建構函式的初始化列表只是說明了變數i的初始值是1,變數j的初始值是i的值。但是並不一定是先初...

C 成員變數的初始化順序

知識點 在c 中,成員變數的初始化順序只與它們在類中宣告的順序有關,而與初始化列表中的順序無關。不知道大家知不知道這個,反正我是不知道 或者忘了 我是在 劍指offer 上看到的,後來在 effective c 中條款4中再次看到,特地在這記錄一下,防止忘記。下面舉個具體的例子,摘自 劍指offer...