2

我正在玩 C++ 中的多个文件,并且我得到了以下示例,但无法编译:

主文件

#include <iostream>
#include "const.hpp"

using namespace std;

int main()
{
    extern double var;
    var = 5;
    cout << var << endl;

    return 0;
}

fct.cpp

#include <iostream>
#include "const.hpp"

using namespace std;

void func()
{
    extern double var;
    cout << var << endl;

}

常量.hpp

#ifndef CONST_H
#define CONST_H

double var;

#endif

我的程序无法编译,因为显然存在 var 的多重定义。我是否正确地假设,基于这个例子,头文件打算用于声明变量,就像我上面的例子一样?

相反,正确的过程是在 .cpp 文件中声明所有变量并使用标题告诉每个(相关)翻译单元 .cpp 文件包含外部(extern)变量?

编辑:我的规则的例外是在处理常量变量(const)时是否正确,它应该在标题中定义?

4

2 回答 2

4

double var;是一个定义 - 在多个文件中包含该标题将违反一个定义规则。如果您想要一个全局(三思而后行),您必须在标题中声明extern double var;它 -并将定义移动到单个实现文件中。

于 2013-02-26T14:14:11.207 回答
3

我是否正确地假设,基于这个例子,头文件不打算用于声明变量,就像我上面的例子一样?

头文件用于声明变量,但您的头文件定义了一个具有外部链接的全局变量,并且它被多次导入。然后链接器合理地抱怨多重定义的符号。

相反,正确的程序是在 .cpp 文件中声明所有变量,并使用标头告诉每个(相关)翻译单元 .cpp 文件包含外部(extern)变量?

是的,除了您不会在该文件中声明全局变量.cpp,而是为它们提供定义

const.hpp

    #ifndef CONST_H
    #define CONST_H

    // ...

    extern double var;
//  ^^^^^^

    #endif

globals.cpp(可以是任何其他.cpp文件,只要它只有一个

    // ...

    double var;

此外,如果您想知道在这种情况下您的包含守卫无法保护您的原因,可能会对您有所帮助。

在处理常量变量 (const) 时,我的上述规则的一个例外是否正确,它应该在标题中定义?

从某种意义上说,是的。默认情况下,全局变量限定为const具有内部链接,这意味着每个翻译单元都将收到该变量的私有副本。因此,即使变量的定义包含在多个翻译单元中,链接器也不会抱怨多重定义的符号。

于 2013-02-26T14:18:34.373 回答