我正在制作一个小的C++框架,其中包含许多.h和.cpp.
我创建了一个包含所有.h文件的常规包含,例如:
framework.h
#include "A.h"
#include "B.h"
#include "C.h"
Run Code Online (Sandbox Code Playgroud)
每个.h标题都受到包含保护的保护
#ifndef A_HEADER
#define A_HEADER
...
#endif
Run Code Online (Sandbox Code Playgroud)
问题是,我希望能够在所有sub .h中包含"framework.h",但是它会导致很多编译器错误:
#ifndef A_HEADER
#define A_HEADER
#include "framework.h"
...
#endif
Run Code Online (Sandbox Code Playgroud)
如果相反,我使用每个子标头的真实头文件,而framework.h用于什么使用我的框架它工作正常..
我只想在所有sub .h中包含主标题,所以我不需要每次都包含所有依赖项.
谢谢 :)
当我包含头文件时,让我们说,
//myheader.h
#ifndef MY_HEADER_H
#define MY_HEADER_H
//....
#endif
Run Code Online (Sandbox Code Playgroud)
成,
//mycpp1.cpp
#include "myheader.h"
Run Code Online (Sandbox Code Playgroud)
我被告知的是,当mycpp1.cpp包含myheader.h时,MY_HEADER_H会被定义,因此任何再次包含它的尝试都将导致错误.
现在,如果我想将它包含在mycpp2.cpp中.
//mpcpp2.cpp
#include "myheader.h"
Run Code Online (Sandbox Code Playgroud)
是否会被包含在内,或者它是否在第一次包含时使用相同的声明?
我知道在头文件中使用包含警戒是为了防止某些内容被定义两次.但是,使用此代码示例,完全没问题:
foo.c的
#include <stdio.h>
#include <string.h>
#include "bar.h"
int main() {
printf("%d", strlen("Test String"));
somefunc("Some test string...");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
bar.h
#ifndef BAR_H_INCLUDED
#define BAR_H_INCLUDED
void somefunc(char str[]);
#endif
Run Code Online (Sandbox Code Playgroud)
bar.c
#include <stdio.h>
#include <string.h>
#include "bar.h"
void somefunc(char str[]) {
printf("Some string length function: %d", strlen(str));
}
Run Code Online (Sandbox Code Playgroud)
上面的代码片段是用编译的,gcc -Wall foo.c bar.c -o foo没有错误.然而,无论是<stdio.h>和<string.h>被列入没有包括后卫.将bar.h删除到单个语句时仍然没有错误void somefunc(char str[]);.为什么没有错误?
我正在做一个小游戏.
在BattleRecord.h中:
#ifndef _CHARACTER_H_
#define _CHARACTER_H_
#include "Character.h"
#endif
class BattleRecord
{
public:
Character Attacker;
Character Defender;
Status status;
int DamageDealt;
int GoldEarned;
int ExpGained;
};
Run Code Online (Sandbox Code Playgroud)
在Character.h中:
#ifndef _EQUIPMENT_H_
#define _EQUIPMENT_H_
#include "Equipment.h"
#endif
class BattleRecord;
class Character
{
BattleRecord AttackEnemy(Character &Enemy);
}
Run Code Online (Sandbox Code Playgroud)
在BattleRecord.h中:
#ifndef _CHARACTER_H_
#define _CHARACTEr_H_
#include "Character.h"
#endif
#ifndef _BATLE_RECORD_H_
#define _BATLE_RECORD_H_
#include "BattleRecord.h"
#endif
class GUI
{
public:
//GUI Methods, and two of these:
void ViewStats(Character &Player);
void Report(BattleRecord Record)
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是,我的Character.h和BattleRecord.h需要相互包含,这肯定会导致多重重新定义问题.因此,我在Character.h中使用了前向声明,添加:
class BattleRecord;
Run Code Online (Sandbox Code Playgroud)
这个问题已经解决了.但是,GUI.h再次需要BattleRecord.h来报告战斗,因此我必须将BattleRecord.h包含在GUI.h中.我还必须包含Character.h才能传入ViewStat函数.我得到了错误并坚持到这个piont.
我有一个.h文件,其中包含几个类定义.我想在这个文件中使用C++的include guard; 但是,我想知道使用包含警卫的哪种方式被认为是正确/正确的?
一名警卫保护一切
#ifndef FOO_BAR
#define FOO_BAR
class Foo
{
};
class Bar
{
};
#endif
Run Code Online (Sandbox Code Playgroud)
或多个单独的警卫.
#ifndef FOO
#define FOO
class Foo
{
};
#endif
#ifndef BAR
#define BAR
class Bar
{
};
#endif
Run Code Online (Sandbox Code Playgroud) 我无法绕过头球和头球后卫。我已经阅读了其他问题及其答案,但仍无法在Visual Studio 2013中完成此工作:
main.cpp#include "stdafx.h"
#include <iostream>
#include "add.h"
int _tmain(int argc, _TCHAR* argv[]) {
std::cout << "3 + 4 = " << add(3, 4) << std::endl;
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
add.cpp#include "stdafx.h" //ADDED LATER; NOW WORKING (AND SEE QUESTION 2 BELOW)
#include "add.h" //ADDED LATER; NOR WORKING (AND SEE QUESTION 2 BELOW)
int add(int x, int y) {
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
add.h#ifndef ADD_H
#define ADD_H
int add(int x, int y);
#endif
Run Code Online (Sandbox Code Playgroud)
编译时,控制台窗口在屏幕上闪烁,然后消失。错误列表包含:
错误1错误LNK2019:函数_wmain c:\ …
我最近开始从事一个项目,我遇到了这个:
#include <string.h> // includes before include guards
#include "whatever.h"
#ifndef CLASSNAME_H // header guards
#define CLASSNAME_H
// The code
#endif
Run Code Online (Sandbox Code Playgroud)
我的问题:考虑到所有(包含的)头文件都是以相同的风格编写的:这是否会导致问题(循环引用等)。并且:是否有任何(好的)理由这样做?
在为包含守卫选择名字时,是否有人遵循的指导方针?我不明白为什么.h文件的名称与include guard中使用的名称略有不同.例如,我见过sphere.h然后#ifndef SPHERE_H_.我可以轻易地使用SPHERE_或者名称必须匹配吗?下划线也是必要的吗?
由于错误,我需要在我的头文件和 Cpp 中实现一个头文件保护,因为在我不知道出了什么问题之前我从未使用过它,因为在某些类上它可以工作,而在一个类上它不会......最初问题更大,但我想我把它缩小到问题的根源。
LedHandler.h
#ifdef LED_HANDLER_H
#define LED_HANDLER_H
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include <FastLED.h>
/* #include "Led/LedFunction.h"
#include "Led/LedStates.h"
#include "Led/Fading.h" */
class LedHandler {
public:
LedHandler(int length, uint16_t pin);
void clear();
void show();
void setColor(int s, int r, int g, int b);
Adafruit_NeoPixel getStrip();
int getLength();
private:
/* LedStates ¤tState;
LedStates &targetState;
Fader<LedStates> &ledFader; */
int length;
Adafruit_NeoPixel strip;
CRGB* leds;
};
#endif
Run Code Online (Sandbox Code Playgroud)
LedHandler.cpp
#ifdef LED_HANDLER_H
#define LED_HANDLER_H
#include <Adafruit_NeoPixel.h>
#include <FastLED.h
#include "Handlers/LedHandler.h"
LedHandler::LedHandler(int length, uint16_t pin) { …Run Code Online (Sandbox Code Playgroud) Why does gcc ignore these header guards in this simple test program?
The header file is:
#ifndef MYHEADER_H
#define MYHEADER_H
#warning "header declared"
int some_int=0;
#endif
Run Code Online (Sandbox Code Playgroud)
And the two .c files are: main.c:
#include "header.h"
int main ()
{
return some_int;
}
Run Code Online (Sandbox Code Playgroud)
source.c:
#include "header.h"
int get_int()
{
return some_int;
}
Run Code Online (Sandbox Code Playgroud)
When compiling with:
gcc -o out main.c source.c
Run Code Online (Sandbox Code Playgroud)
I get the following output:
In file included from main.c:1:
header.h:4:2: warning: #warning "header declared" [-Wcpp]
4 | #warning "header declared" …Run Code Online (Sandbox Code Playgroud) include-guards ×10
c++ ×8
header ×3
c ×2
header-files ×2
arduino ×1
coding-style ×1
esp8266 ×1
gcc ×1
include ×1
macros ×1
platformio ×1