1. 程式人生 > >C++成員變數的初始化順序問題

C++成員變數的初始化順序問題

問題來源:

由於面試題中,考官出了一道簡單的程式輸出結果值的題:如下,

class A
{
private:
	int n1;
	int n2;
	
public:
	A():n2(0),n1(n2+2){}

	void Print(){
		cout << "n1:" << n1 << ", n2: " << n2 <<endl;  
	}
};

int main()
{

	A a;
	a.Print();

	return 1;
}
這時,那個考生這樣回答:n1是2,n2是0。
在我電腦輸出結果為:

如果你也這樣回答,那麼你肯定不懂初始化成員列表的順序。

如果我把A類中建構函式改成:

	A()
	{
		n2 = 0;
		n1 = n2 +2;
	}

那麼此時輸出結果為:

分析:    

1、成員變數在使用初始化列表初始化時,與建構函式中初始化成員列表的順序無關,只與定義成員變數的順序有關。因為成員變數的初始化次序是根據變數在記憶體中次序有關,而記憶體中的排列順序早在編譯期就根據變數的定義次序決定了。這點在EffectiveC++中有詳細介紹。

2、如果不使用初始化列表初始化,在建構函式內初始化時,此時與成員變數在建構函式中的位置有關。

3、注意:類成員在定義時,是不能初始化的

4、注意:類中const成員常量必須在建構函式初始化列表中初始化。

5、注意:類中static成員變數,必須在類外初始化。

6、靜態變數進行初始化順序是基類的靜態變數先初始化,然後是它的派生類。直到所有的靜態變數都被初始化。這裡需要注意全域性變數和靜態變數的初始化是不分次序的。這也不難理解,其實靜態變數和全域性變數都被放在公共記憶體區。可以把靜態變數理解為帶有“作用域”的全域性變數。在一切初始化工作結束後,main函式會被呼叫,如果某個類的建構函式被執行,那麼首先基類的成員變數會被初始化。 

  • bbb的成員變數定義:
  • private:
    • int n1;
    • int n2;
  • bbb的建構函式:
  • bbb::bbb()
  • :n2(1),
  • n1(2)
  • {
  • }
  • 彙編程式碼:
  • 00401535 mov eax,dword ptr [ebp-4]
  • 00401538 mov dword ptr [eax+4],2
  • 0040153F mov ecx,dword ptr [ebp-4]
  • 00401542 mov dword ptr [ecx+8],1
  • 然後依照派生鏈初始化派生類的成員函式。
.總結:    變數的初始化順序就應該是:
  • 1 基類的靜態變數或全域性變數
  • 2 派生類的靜態變數或全域性變數
  • 3 基類的成員變數
  • 4 派生類的成員變數


相關推薦

c++ 類成員變數初始順序

#include <iostream> using namespace std; class A { public: //使用初始化列表初始化時,與定義成員變數的順序有關。 //因為成員變數的初始化次序是根據變數在

C++類成員變數初始順序問題

今天在看劍指offer這本書時,看待一個簡單的舉例,說應聘C++崗位的不知道成員變數初始化順序!我很驚訝,因為我也不知道,所以就看上網查了一下,看到了一個部落格()以及其中的內容,現在將我的學習過程分

成員變數初始順序

 如果建立了物件,則在堆中給類的例項分配記憶體空間, 3.首先,對例項變數,進行預設初始化  (整型為0,浮點型為0.0,布林型為false,字元型為'\u0000',引用型為null)    4.其次,執行例項變數的初始化操作  --例項變數的初始化,使用前2種初始化方式: 宣告時直接初始化和程式碼塊   

Java 構造方法和成員變數初始順序

一定要注意,成員變數按照其宣告的順序會被初始化,並且立刻被初始化為二進位制的0,這個動作發生在所有事件之前,也就是編譯器會立刻將分配給物件的空間初始化。最後就是呼叫類的構造方法了。執行順序: 執行父類靜態程式碼 執行子類靜態程式碼 初始化父類成員變數(我們常說的賦值語句)

Java構造方法、成員變數初始以及靜態成員變數初始三者的先後順序是什麼樣的?

【Java筆試真題】:構造方法、成員變數初始化以及靜態成員變數初始化三者的先後順序是什麼樣的? 【解答】: 當類第一次被載入的時候,靜態變數會首先初始化,接著編譯器會把例項變數初始化為預設值,然後執行構造方法。 Java程式的初始化一般遵循以下三個原則(以下三原則優先順序依次遞減): ①

靜態成員初始順序(C#,java)

前幾天去參加了場筆試,裡面考了靜態建構函式,當時沒做出來,現在對靜態成員的初始化做一個總結。 在c#類中的靜態成員有靜態變數、靜態函式和靜態建構函式,而在java中是沒有靜態建構函式的,取而代之的是靜態程式塊。靜態成員一般存放在靜態區,而且是屬於類的,所以我們可以不用例項化物件,直接呼叫靜態函式,比如工具

static程式碼塊、成員變數初始、構造方法執行順序

下面程式碼: public class Son{ Father father = new Father(); static{ System.out.println("Son static"); } publi

java變數初始順序

在類的內部,變數定義的先後順序決定了初始化順序,即使變數定義分散在方法定義之外,它們依舊會在任何方法(包括構造器)被呼叫之前得到初始化 其中初始化的順序先是靜態物件,其後是非靜態物件 例如: class Cat{ private Dog dog1=new Dog(1)

關於C++的變數初始

建構函式的初始化,不要寫成函式的形式,比如const型別的資料是無法通過:construct(int a) { p1= a; p2 =a; //const 不能直接賦值初始化 p3 =p1; //p3沒有被初始化 } int p1; const int p2; int

Java靜態方法,靜態變數,初始順序

靜態方法的宣告和定義        定義一個靜態方法和定義一個例項方法,在形式上並沒有什麼區別,只是在宣告的頭部,需要加上一個關鍵字static。它的一般語法形式如下: [訪問許可權修飾符] static [返回值型別] 方法名([引數列表]){         語句序列 } 例如下面是一個靜態的方法: pu

淺談java類中成員初始順序(一)

類被建立之後的成員的初始化順序到底是怎麼樣的? 首先 不考慮繼承 package com; public class DemoOne { /** * 關於類的初始化順序 */ //不考慮繼承結構的情況 private static int a;

單例模式中靜態類成員變數初始問題

    最近做一個專案,C++語言,使用到了單例模式做設計。在具體編寫程式碼時,使用了靜態成員變數和靜態函式。程式碼如下: class Camera { private: //(省略若干程式碼) static Camera* pCamera ; //(省略若干

當一個類被載入時成員初始順序

        當一個類因為例項化被載入時,其成員的初始化順序是什麼呢?          先看下面這段程式碼: class Fsx{ public Fsx(){ System.out.println("Fsx無參構造器初始化了"); } public Fsx(

變數初始順序

在一個類裡,初始化的順序是由變數在類內的定義順序決定的。即使變數定義大量遍佈於方法定義的中間,那些變數仍會在呼叫任何方法之前得到初始化——甚至在構建器呼叫之前。例如: //: OrderOfInitialization

類的成員變數初始

[size=medium]public class Test { int E; E = 10; //編譯報錯}類的成員變數(包括final的常量),要麼必須在宣告時同時賦值 要麼就要在構造器中賦值,要麼在程式碼塊中初始化,不可以脫離於宣告單

java 建構函式 成員函式初始順序 以及多型的建構函式的呼叫順序

對於JAVA中類的初始化是一個很基礎的問題,其中的一些問題也是易被學習者所忽略。當在編寫程式碼的時候碰到時,常被這些問題引發的錯誤,感覺莫名其妙。 而且現在許多大公司的面試題,對於這方面的考查也是屢試不爽。不管基於什麼原因,我認為,對於java類中的初始化問

全域性變數初始順序

全域性變數的初始化一般是根據定義的先後順序來的,下面有個例子證明(寫程式時最好不要出現順序問題) #include <stdio.h> #include <string.h> char * initPTR(); bool initBOOL();

C#類的初始順序

類的初始化 就是 執行順序 靜態 初始 副本 只有一個 靜態成員 初始化 類在初始化時的執行順序,依次如下: 1: 子類靜態變量 2: 子類靜態構造函數 3: 子類非靜態變量 4: 父類靜態變量 5: 父類靜態構造函數 6: 父類非靜態變量 7: 父類構造函數

C++的變數初始

C++中變數的初始化有很多種方式,如:預設初始化,值初始化,直接初始化,拷貝初始化,列表初始化。   1、預設初始

[基礎知識]1.C++成員變數初始順序

下列程式的執行結果分別是? class A { private: int n1; int n2; public: A():n2(0),n1(n2+2019){} void Print(){ cout << "n1:" << n1 <<