2010-06-14 151 views
5

我想知道,在C++中,何時發生對象的初始化?
它是在編譯時還是鏈接時間?
對於前:在C++中初始化對象

//file1.cpp 
extern int i; 
int j=5; 

//file2.cpp (link with file1.cpp) 
extern j; 
int i=10; 

現在,什麼是編譯器做的:根據我來說,它分配存儲空間的變量。
現在我想知道:
它是否也會將初始化值放入該存儲中,還是在鏈接時完成?

回答

2

其實有不同的情況:

  • 全局變量或靜態變量(不是類):這些值存儲在exe/dll的init部分。這些值由鏈接器根據編譯的目標文件信息創建。 (初始化加載+將dll/exe映射到內存中)
  • 本地非靜態變量:這些值由編譯器通過將這些值放在堆棧上進行設置(x86上的push/pop)(編譯器初始化)
  • 對象:內存保留在堆棧上,值的實際設置延遲到調用構造函數(運行時初始化)
  • 指向對象的指針(實際上不是新的情況):空間僅爲指針保留。指向的對象只有在調用新的預留內存並調用構造函數初始化後才存在(運行時初始化)
+0

「靜態常量」成員(不是類)呢?他們真的存在作爲一個'變量'?我認爲它們的每一個用法都被值簡單地替換,「靜態常量變量」就消失了。對?其餘的,很好的概述,+1。 – Patrick 2010-06-14 06:05:43

+0

好的。那麼在上面的代碼中,下面的事情會發生嗎?編譯file1.cpp時,編譯器會讓我保持原樣,即不爲i分配存儲空間。 2.編譯器爲j分配存儲空間,但不初始化它。 3.編譯file2.cpp時,編譯器將j保留爲原樣。e不爲其分配存儲空間。 4.編譯器爲我分配存儲空間,但不初始化它。 5.在鏈接file1.o和file2.o時,現在先讓file2.o初始化,那麼現在: j是否獲得初始值0?或沒有被初始化? – 2010-06-14 06:06:06

+0

@帕特里克,好點,我不確定。我想你是對的,因爲變量的成本高於基本類型的內聯值。然而,如果所有的編譯器都這麼做,那麼並不是100%確定的...... – jdehaan 2010-06-14 07:18:34

0

正如你所說的,編譯器爲變量分配存儲空間。我認爲初始化值也將在編譯時完成,而不是在鏈接期間完成。

+0

但是我讀了一本書,認爲編譯器無法確定什麼是值存儲,這就是爲什麼我們不能使用這樣的東西: int a = 5; int arr [a]; – 2010-06-14 05:10:05

+0

@Happy如果編譯器做了足夠多的靜態分析來認識到可以將其轉換爲int arr [5];那就沒問題,但它們通常不會(規範甚至可能不允許) – 2010-06-14 05:13:12

+0

The int a = 5的原因; int arr [a];未定義是因爲數組大小未定義。之後,您可以將a更改爲10,您認爲編譯器如何重新恢復先前聲明的大小。 – ckv 2010-06-14 05:16:14

0

您的示例中沒有任何對象,僅爲int s。如果通過「初始化」,你的意思是什麼時候分配了它們的值,這些int將被轉換爲目標文件中的數據部分中的字大小的條目,該數據部分將用它們的初始值進行硬編碼。數據段,與目標文件的其餘一起,是由編譯器創建的,所以我想回答你的問題是編譯時

+0

如果你考慮OOP那麼我們可以說int也是一個類。 – ckv 2010-06-14 05:15:08

+0

@vis Ints不是C++中的類,它們是原始類型;沒有構造函數調用或任何與類 – 2010-06-14 05:16:47

+0

關聯的其他腳手架。這是正確的。我明白。也許我們必須將問題改爲初始化變量而不是對象。 – ckv 2010-06-14 05:17:51