2013-11-23 64 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'关键字来告诉编译器,定义符号的值是在与由此源生成的对象不同的对象中定义的。这告诉编译器生成一个导入这个符号的对象。链接器然后负责匹配来自对象的导入/导出符号。因此,编译器运行时,您所查找的值不可用,因为它取决于来自另一个对象的外部符号(可能还没有在此时编译)。编译器无法知道符号的值,因此无法使用它。

相关问题