C ++从.CPP文件访问变量

时间:2010-09-07 19:46:22

标签: c++ static namespaces extern

我对.cpp文件之间的变量访问如何工作有点模糊。例如:

的main.cpp

int main()
{
    int a = i;
    return 0;
}

main2.cpp

int i;

这会在main.cpp上生成编译器错误,告诉我i中没有。那么“静态”关键字在这种情况下有什么区别呢? (我尝试使用谷歌搜索,但大多数“静态关键字”信息页面谈论类和功能)

main2.cpp

static int i;

它是一样的吗?是否会阻止extern int i用于访问其他地方的i?匿名命名空间的使用在如何处理变量方面有何不同?

main2.cpp

namespace
{
    int i;
}

总结一下:

  • 可以在.cpp文件之间访问变量吗? (除了extern关键字)
  • 全局变量上的static关键字如何影响事物?
  • 匿名命名空间如何以不同方式影响事物?

3 个答案:

答案 0 :(得分:2)

在您的第一个示例中,main2.cpp定义了一个全局变量i,如果main.cpp声明extern,则{em}可以访问 i已出现在该文件中。 (通常,extern声明来自头文件。)您遇到编译器错误,因为i中从未声明main.cpp,这意味着编译器假定没有这样的变量。

在第二个示例中,main2.cpp定义了文件范围变量i。文件范围变量与全局变量不同,即使它们碰巧具有相同的名称。如果你在第二个例子中在i中有main.cpp的extern声明,那么两个文件都会成功编译,但是你会得到一个链接错误,因为没有< em> global 变量i已定义。

如果您将main2.cpp从第二个示例重命名为main3.cpp,则将i的外部声明添加到main.cpp,编译所有三个并将它们全部链接在一起,成功; main.cpp和main2.cpp将共享一个名为i的变量,而main3.cpp将拥有自己的完全独立的变量,也称为i

这个东西叫做 linkage 。命名空间几乎完全与链接无关。但是,匿名命名空间是特殊的。在匿名命名空间中定义变量用于所有实际目的与使用static定义变量相同 - 它使其成为文件范围变量。 (如果我没记错的话,那就有区别,但只有你使用导出的模板做复杂的事情才有意义,并且由于导出的模板使用得很少,以至于他们正在谈论从C ++标准中删除该功能,所以你不要我不得不担心它。)

匿名命名空间的值是您可以在其中放置类定义,这使得所有类的方法都是文件本地的。 (只有class { ... }块必须在namespace { ... }块内才能产生这种效果。)你不能以任何其他方式做到这一点。

答案 1 :(得分:1)

所有全局变量都有某种链接。需要extern链接来在不同文件之间的不同上下文中命名相同的变量。

extern是默认值。如果您在变量声明中实际使用extern,则将其视为对另一个文件的引用。省略任何链接说明符以实际创建变量;这必须只在一个文件中发生。

extern int i; // i exists somewhere in some .cpp file.
int i; // ah! this is the file it exists in. 
       // (Although nothing special about that.)
应用于全局(命名空间范围)的

static使其成为文件的本地。您从私有名称空间获得相同的效果,因此不推荐使用函数或类范围之外的static。许多人仍然使用它。

static规则的例外意味着文件本地在类和inline函数中。类static成员应该更恰当地称为extern,因为语义是相同的。它很丑陋而令人困惑,但我想Bjarne只想将extern作为关键字消除。

内联函数在多个.cpp文件中可以具有相同的定义,因此当创建static变量时,也会共享变量定义。

答案 2 :(得分:0)

  • 是的,例如你可以使用静态类变量
  • 它使变量本地和持久到编译单元
  • 匿名命名空间可防止符号之间发生冲突。就像你手动创建唯一命名的命名空间一样