Codegear RAD Studio 2009中是否需要"冗余包括警卫"?编译器是否足够聪明,可以自行处理?
例如,我可能在foo.h中有以下'include guard':
#ifndef fooH
#define fooH
// ... declaration here
#endif
Run Code Online (Sandbox Code Playgroud)
以及use_foo.h中的以下'冗余包含保护':
#ifndef fooH
#include "foo.h"
#endif
Run Code Online (Sandbox Code Playgroud)
此外,如果编译器不够智能,如果它们包含在源文件中,那么"冗余包括警卫"是必需的.例如use_foo.cpp.?
这是在命名空间中使用函数的正确方法吗?我将在多个文件中#include?
test.h
#pragma once
#ifndef TEST
#define TEST
namespace test{
namespace {
bool test(){
return true;
}
}
}
#endif //TEST
Run Code Online (Sandbox Code Playgroud) 我已经在头文件中使用了一段时间的保护,我理解为什么使用它们的唯一原因是在编译时启用单个包含此内容(包含保护的头文件).
我想知道是否有任何其他原因使用标题保护,为什么它们没有在.c文件中使用,如果保护用于.c文件会发生什么?
答.从以下回复中收集.
通常,所有定义都进入.c文件,头文件(.h文件)包含所有声明.包含.c文件不是一个好习惯.
为了在编译特定于翻译单元的过程中只与一个包含的.c文件可用的声明相关联(因此,如果有两个或更多的库需要链接;即,我们有两个或更多翻译单位); 标题保护有助于包含头文件ONLY ONCE.
这是因为预编译器阶段甚至在编译文件以获取对象(.o扩展名)文件之前.预处理器阶段替换整个宏并包含相关数据,这些数据只允许包含.h文件一次.
我正在经历实现定义的行为控制
并且有以下与 相关的文字#pragma once:
与头文件保护不同的是,这个 pragma 使得不可能在多个文件中错误地使用相同的宏名称。
我不确定这意味着什么。有人可以解释一下吗?
TIA
我想以这样的方式定义一个自动返回类型的函数,如果包含标头,我可以从多个 .cpp 文件中调用它。我有4个文件
\nhead.hpp- 函数在哪里
#ifndef HEAD_HPP\n#define HEAD_HPP \n\nauto f();\n\n#endif\nRun Code Online (Sandbox Code Playgroud)\nhead.cpp- 函数声明的位置
#include "head.hpp"\n\nauto f(){\n return [](){\n return 10;\n };\n}\nRun Code Online (Sandbox Code Playgroud)\ntest1.cpp- 使用地点
#include "head.hpp"\nint foo(){\n auto func = f();\n return f();\n}\nRun Code Online (Sandbox Code Playgroud)\nmain.cpp- 也用在哪里
\n#include "head.hpp"\nint foo();\nint main(){\n auto fu = f();\n\n return fu() + 5 + foo();\n}\nRun Code Online (Sandbox Code Playgroud)\n所有文件都编译在一起\n我仍然收到错误:
\n\n\n错误:在扣除 \xe2\x80\x98auto\xe2\x80\x99 之前使用 \xe2\x80\x98auto f()\xe2\x80\x99
\n
\n\n自动 fu = f();
\n
我想std::string在我的头文件中提供一些使用的内联便利函数以及使用的库函数const char *,但我不想包含<string>. #ifdef如果<string>是这种情况,我想检查是否包含并提供便利功能。
问题:对于所有 STL 实现,STL 标头中标头保护的名称是否相同?在 Visual Studio 2010 中,头文件保护<string>是_STRING_.
我有这个文件logger.hpp:
#ifndef _LOGGER_HPP_
#define _LOGGER_HPP_
#include "event.hpp"
// Class definitions
class Logger {
public:
/*!
* Constructor
*/
Logger();
/*!
* Destructor
*/
~Logger();
/*!
* My operator
*/
Logger& operator<<(const Event& e);
private:
...
};
#endif
Run Code Online (Sandbox Code Playgroud)
而这个文件是event.hpp
#ifndef _EVENT_HPP_
#define _EVENT_HPP_
#include <string>
#include "logger.hpp"
// Class definitions
class Event {
public:
/*!
* Constructor
*/
Event();
/*!
* Destructor
*/
~Event();
/* Friendship */
friend Logger& Logger::operator<<(const Event& e);
};
#endif
Run Code Online (Sandbox Code Playgroud)
好.在logger.hpp中我包含event.hpp,在event.hpp中我包含logger.hpp.
我需要包含event.hpp,因为在logger.hpp中我需要定义运算符.
我需要包含logger.hpp,因为在event.hpp中,要在类Event中定义友谊.
当然,这是一个循环递归.
我试过这个: …
在C++中,我有一个双重包含问题:
文件stuffcollection.h
#pragma once
#ifndef STUFFCOLLECTION_H
#define STUFFCOLLECTION_H
#include "Stage.h"
class Stuffcollection {
public:
bool myfunc( Stage * stage );
};
#endif // STUFFCOLLECTION_H
Run Code Online (Sandbox Code Playgroud)
文件stage.h:
#pragma once
#ifndef STAGE_H
#define STAGE_H
#include "Stuffcollection.h"
class Stage {
// stuffcollection used in stage.cpp
};
#endif // STAGE_H
Run Code Online (Sandbox Code Playgroud)
编译器错误:
\Stuffcollection.h|(line were bool myfunc is declared)|error: 'Stage' has not been declared|
||=== Build finished: 1 errors, 0 warnings ===|
有人可以解释为什么会发生这种情况以及如何解决这个问题?我已经使用include guard和pragma一次预处理器指令,它只是不起作用.
(如果我#include "Stuffcollection.h"从stage.h中删除并注释掉在stage.cpp中使用它的相应行,那么我的其余代码就可以正常工作了.这真的只是在将Stuffcollection包含到舞台中时突然停止工作.)
PS:舞台只是一个例子,我几乎每隔一个文件都使用stuffcollection,每次我都遇到这个问题.
编辑:我按照建议,现在的问题是invalid use of incomplete type,即虽然给出的答案解决了循环依赖的问题,但他们没有解决我正在处理的问题.我的问题在 …
我正在尝试创建一个头文件(包括我为AVL Trees编写的函数),但我有一个小问题和对包含警卫的语法的误解.
现在我的代码看起来像这样
#ifndef STDIO_H
#define STDIO_H
#endif
#ifndef STDLIB_H
#define STDLIB_H
#endif
#ifndef CONIO_H
#define CONIO_H
#endif
Run Code Online (Sandbox Code Playgroud)
问题是,我认为它只包括<stdio.h>.当我尝试使用malloc时,它表示malloc未定义,即使我包含了stdlib.
根据http://www.cprogramming.com/reference/preprocessor/ifndef.html,如果我理解正确,ifndef检查是否定义了令牌,如果它不是,它定义我在ifndef之后写的所有内容,直到#endif.所以我的代码应该工作.
是否定义了stdio?没有.所以定义它.万一.是stdlib定义的吗?没有.所以定义它.万一.是conio定义的吗?没有.所以定义它.万一.我没有看到问题.
如果我想添加这3个标题,那么正确的语法是什么?
你看,我一直在尝试创建一个std::vector包含Entity类中类的IState类.这两个类都是接口.
错误是
"实体"未在此范围内声明
并指出:
protected:
std::vector <Entity*> ent_map;
Run Code Online (Sandbox Code Playgroud)
在IState.h中
我一直在努力解决它.一旦我在IState.h中做了一个前向声明,但是一旦我做了并尝试使用向量,它就会发出它是一个不完整的类,所以我回到原点.
有任何想法吗?
Entity.h
#ifdef __ENTITY__
#define __ENTITY__
#include <iostream>
#include <SDL.h>
class Entity
{
public:
virtual ~Entity();
virtual void load(const char* fileName, std::string id, SDL_Renderer* pRenderer) = 0;
virtual void draw() = 0;
virtual void update() = 0 ;
virtual void clean() = 0;
/*void int getX() { return m_x;}
void int getY() { return m_y;}
void std::string getTexID {return textureID;}
*/
};
#endif // …Run Code Online (Sandbox Code Playgroud) include-guards ×10
c++ ×8
include ×4
header ×3
c ×2
pragma ×2
auto ×1
header-files ×1
lambda ×1
macros ×1
namespaces ×1
stl ×1