为什么#ifndef在这种情况下不起作用
Why does #ifndef not work in this situation?
注意:这个问题已经在这里得到了明确的回答
问题不包括警卫:他们不会帮助不同的人翻译单位
注意:我知道解决方案是使用extern
关键字
我是C++新手。我在理解头文件中的#ifndef
时遇到问题。当我做这样的事情时,我得到一个错误,说变量game_over
和turn
已经定义好了。
/*chess.h*/
#ifndef CHESS
#define CHESS
#include <iostream>
#include "chessboard.h"
using namespace std;
bool game_over;
char turn;
chessboard board;
int main();
#endif
/*bishop.cpp*/
#include "bishop.h"
#include "chess.h"
bishop::bishop(string pos, char color)
{
int x = pos[0] - 97;
int y = pos[1] - 1;
name = "bishop";
this->color = color;
board.add_new(*this);
}
/*chess.cpp*/
#include "chess.h"
int main()
{
...
}
为什么变量在这里定义了两次?我认为第一次包含chess.h
时,定义了CHESS
。因此,在bishop.cpp中,#include "chess.h"
将不执行任何操作,因为标头将从#ifndef CHESS
跳到#endif
。但它显然不是这样工作的。为什么我错了?
#ifndef
仅在#ifndef
之前的同一翻译单元中定义符号时才会阻止代码。翻译单元是一个源文件(.cpp)和包含在其中的所有文件。由于您正在编译两个源文件,因此它们都将完全包含.h文件。
您似乎已经知道如何处理在头文件中定义全局变量的问题:在头中声明它们extern
,并将定义放入其中一个源中。不过,如果我一开始就没有警告你要避免全局性的,那我就太失职了,因为随着你的程序的发展,它们会让你的生活变得困难。
相关文章:
- G++ C++17 类模板参数推导在非常特殊的情况下不起作用
- 为什么在这种情况下,前向声明不起作用?
- 为什么 std::void_t 在这种情况下不起作用
- 为什么在这种情况下 boost::recursive_wrapper 不起作用
- 为什么在这种情况下创建临时实例不起作用?
- 为什么SFINAE在这种情况下不起作用?
- 为什么在这种情况下转发引用不起作用?
- 在这种情况下,过载不起作用
- 为什么模板论点不能在这种情况下推导
- 请帮助我理解为什么SFINAE在这种情况下不起作用
- 为什么#ifndef在这种情况下不起作用
- 为什么c_str在这种打开(文件名)的情况下不起作用
- 在这种情况下__declspec( align( # ) ) 不起作用
- 为什么cvPutText在这种情况下不起作用?
- 在这种情况下,最小和最大根本不起作用?
- 内联扩展可能不起作用的情况
- 为什么贪婪的方法在这种情况下不起作用?
- 为什么 std::function<boost::any ()> 在这种情况下不起作用?
- 为什么在这种情况下"自动"不起作用?
- 为什么多态性在这种情况下不起作用