我正在使用C ++中的多个文件,并且我使用以下示例而未编译:
的main.cpp
#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;
}
const.hpp
#ifndef CONST_H
#define CONST_H
double var;
#endif
我的程序没有编译,因为显然有一个var的多重定义。我是否正确地假设,基于此示例,头文件不旨在用于声明变量,如上例所示?
相反,正确的过程是声明.cpp文件中的所有变量并使用标头告诉每个(相关的)翻译单元.cpp文件包含外部( extern )变量?
编辑:上面对我的规则的一个例子处理常量变量(const)是否正确,这应该在标题中定义?
答案 0 :(得分:4)
double var;
是一个定义 - 包括多个文件中的标头将违反一个定义规则。如果你想要全局(三思而行),你必须在标题中{strong>声明 - extern double var;
并将定义移动到单个实现文件中。
答案 1 :(得分:2)
我是否正确地假设,基于此示例,头文件不打算用于声明变量,如上例所示?
头文件用于声明变量,但是头文件定义具有外部链接的全局变量,并且它被多次导入。接着然后合理地抱怨多重定义的符号。
相反,正确的过程是声明.cpp文件中的所有变量并使用标头告诉每个(相关的)翻译单元.cpp文件包含外部(外部)变量?
是的,除了你不会声明该.cpp
文件中的全局变量,而是为它们提供定义。
const.hpp
#ifndef CONST_H
#define CONST_H
// ...
extern double var;
// ^^^^^^
#endif
globals.cpp
(可以是任何其他.cpp
文件,只要只有一个)
// ...
double var;
此外,如果您想知道在这种情况下包含警卫不能保护您的原因,this可能对您有所帮助。
上面我的规则的例外处理常量变量(const)是否正确,这应该在标题中定义?
从某种意义上说,是的。限定为const
的全局变量默认具有内部链接,这意味着每个翻译单元将接收该变量的私有副本。因此,即使多个翻译单元包含变量的定义,链接器也不会抱怨多重定义的符号。