2013-11-23 67 views
1

我不太明白在C++中使用externconst關鍵字的背後的概念。爲什麼我不能使用外部常量定義數組?

我已閱讀了有關該主題的一些相關問題(請參閱下面的),但到目前爲止,我一直無法掌握如何將它們一起使用。

相關問題:

好的,採取例如以下的程序代碼:

dConst.hpp

extern const int NUM_GENERATORS; // Number of generators in power plant 

extern const int generatorID[NUM_GENERATORS]; // Generator ID numbers 
extern const bool generatorStatus[NUM_GENERATORS]; // Generator Status 

vConst.cpp

const int NUM_GENERATORS = 4;  // Generators in Power Plant 

const int generatorID[NUM_GENERATORS] = // Generator ID numbers 
{ 
    23, 57, 49, 106 
};  
const bool generatorStatus[NUM_GENERATORS] = // Production status (online?) 
{ 
    true, false, false, true 
}; 

的main.cpp

#include <iostream> 
#include "dConst.hpp" 

using std::cout; 
using std::cin; 
using std::endl; 

// ----====< M A I N >====---- 
int main() 
{ 
    for (int iGenerator = 0; iGenerator < NUM_GENERATORS; iGenerator++) 
    { 
     cout << "Generator "; 
     cout << generatorID[iGenerator]; 

     if (generatorStatus[iGenerator]) 
      cout << "is running." << endl; 
     else 
      cout << "is offline!" << endl; 
    } 

    cout << "Press ENTER to EXIT:"; 
    cin.get(); // Stop 

    return 0; 
} 

我無法使用NUM_GENERATORS來聲明我的數組充滿發生器ID和狀態。我已經在頂部包含了外部定義:#include "dConst.hpp。從我讀過的一些StackOverflow問題(可能不夠緊密),編譯器和鏈接器應該能夠找到在vConst.cpp中定義的值,並繼續他們的快樂方式。

那麼他們爲什麼不這樣做呢?

回答

2

鏈接器可以找到它,但編譯器不能,因爲它在不同的編譯單元中。編譯器需要在編譯時知道數組的大小,但只有在鏈接時才知道該常量是否聲明爲extern。

+0

所以我需要將這些常量的聲明包含在* vConst.cpp *到* main.cpp *中。如果我必須在另一個源文件中使用這些相同的常量,比如* powerPlant.cpp *,那麼我不會最終重新聲明那些常量[One Definition Rule](http://stackoverflow.com/questions/) 4192170 /什麼,恰好是一定義規則,在-C)? –

2

Pollex先生是完全正確的,但我想我可能會擴展他的回答,以便在未來尋找這些信息的人可能會有更完整的畫面。通常現代IDE隱藏了將源代碼轉換爲可執行二進制文件所涉及的多個部分。

一般來說,C/C++編譯器只處理文本文件(源文件)。編譯器讀取這些文件,解析它們並輸出目標文件。目標文件包含二進制可執行部分和符號部分。鏈接器然後運行以將各種二進制對象文件「鏈接」到單個可執行文件中。它通過將請求的符號與可用符號進行匹配來實現。

如果您已經介紹過,您正在使用'extern'關鍵字來告訴編譯器,定義符號的值是在與由此源生成的對象不同的對象中定義的。這告訴編譯器生成一個導入這個符號的對象。鏈接器然後負責匹配來自對象的導入/導出符號。因此,編譯器運行時,您所查找的值不可用,因爲它取決於來自另一個對象的外部符號(可能還沒有在此時編譯)。編譯器無法知道符號的值,因此無法使用它。

相關問題