编辑:正确的功能名称,并添加了#pragma一次
这是我的问题的一个非常强大的简化,但如果我这样做:
A.H
#pragma once
static int testNumber = 10;
void changeTestNumber();
A.cpp
#pragma once
#include "A.h"
void changeTestNumber()
{
testNumber = 15;
}
B.h
#pragma once
#include "A.h"
// some other stuff
B.cpp
#pragma once
#include "B.h"
// some other stuff
的main.cpp
#pragma once
#include "B.h"
#include <iostream>
int main(){
changeTestNumber();
std::cout<<testNumber<<std::endl;
return 0;
}
为什么我在呼叫时没有得到testNumber = 15? 当我使用包含在我的包含标题的标题中的函数时,会发生什么? 如果我从 int testNumber 中删除 static ,我将得到一些关于我的testNumber被初始化两次的错误。
当我这样做时,我的标题编译了两次吗?
提前致谢!
答案 0 :(得分:5)
除了明显不正确的命名(我假设只是匆忙创建一个类似的例子并且不是代码中的实际问题),你需要在.h中将变量声明为extern
/.hpp文件。您不能拥有extern
变量也是static
,因为static
的(一个)用途是将变量包含在一个.cpp
中文件。
如果你改变:
static int testNumber = 10;
在A.h
文件中:
extern int testNumber;
然后在A.cpp
文件中执行以下操作:
#include "A.h"
int testNumber = 10;
现在继续运行:
int main() {
//changeNumber();
std::cout << testNumber << std::endl; // prints 10
changeTestNumber(); // changes to 15
std::cout << testNumber << std::endl; // prints 15
std::cin.ignore();
return 0;
}
务必修复功能名称!
答案 1 :(得分:3)
Goodies和其他人肯定是正确的,但让我再提前一步:
static
将定义定义为翻译单元的本地定义。因此,在标题中定义静态全局变量将导致与包含它的翻译单元一样多的副本。除非那不是你想要的那不是那种方式
extern
告诉编译器全局变量存在于某处,但未定义,必须在链接阶段进行搜索。要使链接器成功,您需要在某处定义它(通常是存在更有意义的源文件)
省略它们将导致“多重定义”链接器错误,其中多个源包含标题。
现在,2 nd 案件有两个限制:
为避免这一切,请考虑
inline
,则全局定义的函数可以链接更多次并且您可以在标题中定义全局值,方法是将它们设置为函数的局部值:例如
inline int& global_val() //note the &
{ static int z = 0; return z; }
唯一缺点是每次访问时始终放置()
。
由于本地值是唯一的并且在调用时被实例化,这将确保,如果全局变量之间存在依赖关系(将int z=0
视为int z=something_else()
),它们将按照它们的顺序创建即使在递归和多线程的情况下(从c ++ 14开始)
考虑到C ++向泛型和函数范式的演变,并考虑将所有源放在单个编译单元中比连接多个源更有时间...考虑不使用全局变量,而是用内联instatiator 功能。
约2年后编辑:
C ++ 17最终为变量声明引入了内联指令,就像函数扩展的语法快捷方式一样。
所以 - 今天 - 你可以简单地写
inline const float PI = 3.14159;
inline int goodies = 25;
答案 2 :(得分:1)
A.H
extern int testNumber;
void changeNumber();
A.cpp
#include "A.h"
int testNumber = 10;
void changeTestNumber()
{
testNumber = 15;
}
B.h
#include "A.h"
// some other stuff
B.cpp
#include "B.h"
// some other stuff
的main.cpp
#include "B.h"
#include <iostream>
int main(){
changeTestNumber();
std::cout<<testNumber<<std::endl;
return 0;
}
请尝试那样。