.h中的声明。在.cpp中的定义。正确的?

时间:2017-02-27 02:29:58

标签: c++ global-variables declaration definition

令人难以置信。 30多年来我一直在编程,我似乎忘记了如何处理全局变量。 (这是因为我猜我从未真正使用它们。)在头文件中我有 -

// any.h
bool neat;

和cpp -

// any.cpp
#include <any.h>
bool neat = false;
它告诉我,我正在重新定义。所以我拿出了“bool&#39; -

// any.cpp
#include <any.h>
neat = false;

现在它告诉我&#34; 错误:'neat'没有命名类型&#34; 它怎么能不知道&#39;整洁&#39;是一个布尔?它是相同的翻译单位 所以我不需要 extern 。我还没有声明任何静态 所以我知道文件范围没有限制。这应该是 全局变量。

我对声明和定义之间区别的理解是 通过&#39;声明&#39;你只是告诉编译器一个名字是 特定类型。鉴于&#39;定义&#39;编译器实际设置 在可执行文件中放置一些空格以存在名称。

我做错了什么?

3 个答案:

答案 0 :(得分:2)

您需要在头文件中使用extern关键字(并将bool保留在.c文件中)

// any.h
extern bool neat;

// any.cpp
#include <any.h>
bool neat = false;

这样做的原因是让链接器知道在任何对象中的任何位置都有该名称的变量,但是在使用该变量的每个对象中都没有为它保留内存。但是,在实际定义变量的对象中,您必须像对非导出变量那样定义它。

答案 1 :(得分:2)

请注意,bool neat;(和bool neat = false;)是definition;这意味着如果你把它们都放在头文件和实现文件中,你就会得到多个定义错误。

您可以使用extern将其更改为声明,

  

此外,使用extern且没有初始值设定项的变量声明不是定义。

e.g。您可以在头文件中将它们声明为

extern bool neat; // declaratioin

并在实现文件中将它们定义为

bool neat;        // definition
                  // or bool neat = false; same effect here

关于第二个代码段的错误,注意neat = false;不是声明也不是定义;它是一个声明(赋值),必须放在一个函数中。 e.g。

// any.h
bool neat; // definition

// any.cpp
#include <any.h>
void init_neat() { 
    neat = false;
}
int main() {
    init_neat();
    // use neat ...
}

答案 2 :(得分:0)

在评论中,你说:

  

你的意思是作为类(或命名空间)中的函数吗?或者你的意思是全球功能?如果是这样,那么拥有两个全局名称(setNeat和getNeat)而不是一个(整洁)会更好吗?

函数是在命名空间中还是全局函数并不重要。 IMO,最好通过函数提供对数据的访问,而不是通过全局变量访问数据。

您可以在函数的实现中使用各种选项。

  1. 您可以使用变量来维持状态。
  2. 您可以将函数调用传递给另一个实现维持状态的函数。
  3. 您可以使用聚合对象(如struct)来维护应用程序的许多其他全局状态。
  4. 当您通过函数提供对数据的访问时,您可以选择能够更改数据的维护方式和位置。