2010-06-21 58 views
1

請告訴我,從C++開始執行的地方,希望你的答案是「從主要的」。開始執行

那該怎麼辦?

class abc 
{ 
public: 
    abc() 
    { 
     cout<<"hello"; 
    } 
}; 

const abc obj; 

int main() 
{ 
    cout<<"Main"; 
} 

輸出:

helloMain 

請詳細說明。

+1

我想你需要考慮你的意思是「哪裏開始執行」什麼,因爲剛關於每個編譯語言都會有一些代碼在您編寫的第一條語句之前運行。 – 2010-06-21 11:33:19

回答

4

從您的意見到其他答案支柱,這聽起來像一個10,000英尺的視圖可能有助於理解。

啓動應用程序所涉及的確切步驟在操作系統,編譯器和編程語言中各不相同,但「一般」過程基本相同。

  1. OS內核被要求開始運行目標可執行
  2. 內核創建一個新的進程來承載exectuable
  3. 內核建立了基本的進程屬性的新工藝:文件描述符,環境變量,安全屬性等。
  4. 內核運行用戶模式的「加載程序」,以實際打開連接可執行文件的文件並準備好執行
  5. 加載程序讀取包含可執行文件的文件並將其分解爲各種段:全局變量數據,可執行代碼等
  6. 加載程序解析任何動態鏈接庫符號並正確地爲可執行代碼佈置內存(實質上,這一步涉及確保程序中的所有指針指向正確的位置)
  7. 然後loder調用可執行文件的「入口」功能。但是,這不是你的'主要'功能。 '入口'函數通常被操作系統/編譯器隱藏,以允許運行主前置初始化代碼。
  8. 在C++的輸入功能的情況下,將最有可能看起來像以下:

int __entry(int argc, char *argv[]) 
{ 
    // configure standard I/O streams, threading tables, & other utilities 
    initialize_c_runtime(); 

    // run the constructors for all static objects 
    initialize_static_cplusplus_objects(); 

    // Now, finally, after *all* that we execute the 'main' function 
    return main(argc, argv); 
} 
+1

謝謝:) 非常有幫助。 – Sadique 2010-06-22 13:11:49

12

調用main之前,會創建全局變量(並因此調用其構造函數)。


答到OP的評論:

如果你想挖比你寫的代碼更深入的,有事情main之前發生的事情被調用,而我自己也沒有一個清晰的畫面。我正在談論我們編寫的代碼 - 入口點是main函數,在初始化全局變量後調用該函數。碰巧,類實例的初始化意味着調用它的構造函數。

因此簡而言之,行const abc obj;創建一個abc類型的全局變量,它在調用main之前被初始化(它是調用print語句的默認構造函數)。因此,輸出helloMain

+0

@strut請參閱更新 – Amarghosh 2010-06-21 13:09:32

3

您聲明obj作爲類abc的常量變量。變量obj在程序開始執行之前由編譯器提供的代碼分配一個默認值。此代碼調用默認構造函數以創建abc類型的默認對象,並將其指定給obj

拋開靜態初始化,說從main()開始執行是正確的。

0

由於obj是一個全局對象,它將在main執行之前實例化。它就像任何其他全局變量一樣,即當你將整型變量聲明爲全局變量時,它包含0,而不是任何垃圾值。因此,您的對象正在實例化,並調用構造函數,然後打印hello字符串。

0

應用程序不從main啓動。以下是從主開始有些堆棧快照(對於一個控制檯應用程序,Unicode版本),用VS2005編譯:

MyApp.exe的wmain(INT ARGC = 00000001,爲wchar_t * argv的= 0x00364d68)線! 67 C++

myapp.exe!__tmainCRTStartup() Line 594 + 0x17 bytes  

[email protected]() + 0x23 bytes  

第一功能,可以說以在用戶模式中的新進程上下文中運行是BaseProcessStart,這是一個Win32電平函數。它調用CRT級mainCRTStartup,它使用二進制映像本身中的各種數據段來運行各種初始化程序 - 例如全局構造函數,如obj。事實上,你可以在你的ctor中設置一個斷點並自己看:

myapp。exe文件!`動態初始化for'obj ''()

MSVCR80.DLL!_initterm(...)

MyApp.exe的!__ tmainCRTStartup()

[email protected]()

(在那裏有一些格式化的困難)。 initterm是對全局對象進行迭代並調用其構造函數的函數。

在不同的平臺和編譯器上(甚至在VS上,MFC應用程序非常不同),堆棧看起來不同,但這個想法總是相同的:運行時使用二進制映像信息初始化全局對象主要進入。

+0

請注意,您將以非標準模式顯示VC++(使用'wmain()',但這並不完全有效,但是當調用入口點時,將使用調用全局變量的ctors的相同隱藏函數是標準的'int main(int argc,char ** argv)' – MSalters 2010-06-21 11:39:19

+0

我明確地注意到它是一個unicode版本。什麼不是完全有效的? – 2010-06-21 11:43:54

+0

這是問題!現在你真的認爲我有任何線索你說什麼先生Shilon !! 重申我對你的解釋無能爲力! – Sadique 2010-06-21 12:34:41