这里需要extern关键字,const在cpp文件中

时间:2014-07-11 13:07:07

标签: c++

如果我有头文件

namespace Bob
{
    extern const T x;
};

在源文件中

extern const T Bob::x = 123;

源文件中的第二个extern是必需的还是可选的?

我搜索过并发现了相互矛盾的信息。

从这个网页: http://msdn.microsoft.com/en-us/library/357syhfh.aspx

但是要在C ++中获得相同的行为,您必须将您的const变量[在源文件中]声明为:

extern const int i = 2;

2 个答案:

答案 0 :(得分:3)

通常,extern关键字告诉编译器不要定义符号,因为它将在其他地方定义。所以写一下。

namespace Bob {
    extern T x;
}

没有定义变量x,而是声明它。您可以拥有任意数量的extern声明。但是,如果您不提供定义,则链接将失败。所以你必须定义

T Bob::x;

代码中的某处以提供定义。

const关键字在这里有点特殊,因为它意味着内部链接。这意味着,x的定义在定义它的特定编译单元之外将不可见。要改变这种行为,你需要写

    extern const T Bob::x = 123;

如果您希望xconst,并从其他编译单元引用它。

----另一个编辑----
只是为了绝对清楚: 如果const变量应该在其编译单元之外引用,那么必须明确声明它extern

但是,如果声明与定义分开给出,则定义不一定需要再次指定关键字extern。另一个示范示例:

<强> myheader.h

extern const int i;

这声明i带有外部链接的const整数,但没有定义它。

main.cpp,版本1

#include "myheader.h" //Through the include, the above declaration of `i` comes before its definition.

const int i=123; // Although the `extern` modifier is omitted here,
                 // it's still in effect because we already declared `i` as `extern`
                 // Therefore it makes no difference here, whether or not you specify `extern` again.
                 // The compiler knows this is a definition either way, because of the initialization.

main.cpp,版本2

//#include "myheader.h"

extern const int i=123; // this line is declaration and definition in one, because we did not include
                        // the declaration from myheader.h. Thus, to tell the compiler that you want
                        // `i` with external linkage, you MUST specify `extern`. Otherwise you'll get
                        // internal linkage.

我希望这一切现在对你有意义。

答案 1 :(得分:0)

您可以使用staticextern关键字控制符号的关联。对于非const符号,默认链接为extern,对于命名空间范围的const符号,默认链接为static(即内部)。这适用于C ++,但不适用于C(您必须将其声明为static才能使其具有内部链接)。

所以,如果你有

const int i = 2;

进入.c文件,然后通过声明

将其用于另一个单元
extern const int i;

在C中很好,因为该变量默认具有外部链接(并且使用extern关键字指示编译器将其找到另一个单元),但在C ++中相同

const int i = 2;

进入一个.cpp文件(坚定我写的内容)有内部链接,它必须用

定义
extern const int i = 2;

明确拥有外部链接,并能够用

进入另一个单位
extern const int i;

最后,当你初始化一个全局变量时,你总是在中定义它 >,这意味着以下内容完全有效:

#include <iostream>
using namespace std;

#define T int

extern const T x; // This is a declaration
extern const T x = 123; // This is a definition

int main() {

  std::cout << x; // 123

  return 0;
}

这意味着第二个&#39; extern&#39;关键字也是不必要的。