我不太了解在C ++中使用extern
和const
关键字背后的概念。
我已经阅读了一些关于这个主题的相关问题(见下文),但到目前为止,我还没有掌握如何一起使用它们。
相关问题:
extern
, but how? 好的,例如以下程序代码:
的 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 中定义的值,并继续他们的快乐方式。
那他们为什么不这样做?
答案 0 :(得分:2)
链接器可以找到它,但编译器不能,因为它位于不同的编译单元中。编译器需要在编译时知道数组的大小,但只有在常量被声明为extern时才会在链接时知道。
答案 1 :(得分:2)
先生。 Pollex是完全正确的,但我想我可能会扩展他的答案,以便将来寻找这些信息的人可能会有更完整的画面。现代IDE经常掩盖将源代码转换为可执行二进制文件所涉及的多个部分。
从广义上讲,C / C ++编译器只处理文本文件(源文件)。编译器读取这些文件,解析它们并输出目标文件。对象文件包含二进制可执行部分和符号部分。然后链接器运行以将各种二进制对象文件“链接”到单个可执行文件中。它通过将请求的符号与可用符号相匹配来实现。
在您提供的情况下,您使用'extern'关键字告诉编译器定义的符号的值是在与此源生成的对象不同的对象中定义的。这告诉编译器生成一个导入该符号的对象。然后,链接器负责匹配对象中的导入/导出符号。因此,当编译器运行时,您要查找的值不可用,因为它依赖于来自另一个对象的外部符号(在该点可能甚至没有构建)。编译器无法知道符号的值,因此无法使用它。