我在使用extern的翻译单元中删除了两个标题包含。这是可取的吗?
我的具体情况:我有一个名为ParseTree
的课程,累积Token*
个。{ ParseTree*
是Parser
的私人成员。
最初,我在parse_tree.cc
中有以下几行。
#include "parser.h"
#include "token.h"
在分析了我的代码之后,我将实际具有外部依赖关系的两个函数隔离开来,并用以下内容替换了包含:
extern std::ostream& operator<<(std::ostream& out, const Token& t); // @token.h
extern bool hasPriority(const Token* p_tok1, Token* p_tok2); // @parser.h
两种解决方案似乎都有效。在选择extern over include时,我是否应该注意隐藏的危险?
答案 0 :(得分:8)
如果您使用extern
声明,则无需通过在使用它的任何地方重新设置函数原型来重复自己。使用头文件,如果要更改原型,只需在一个位置更改它。
所以不,当你已经有一个合适的头文件时,不要使用extern
。
答案 1 :(得分:1)
两种解决方案似乎都有效。在选择extern over include时,我是否应该注意隐藏的危险?
是。 API可能正在更改,编译器将无法为您工作,它将对您不利。
学习如何使用编译器。不,不仅“现在”,从长远来看,我的意思是。从长远来看,你犯了愚蠢的错误,而不是在你脑子里有一切新鲜的时候。是的,你的大脑记忆力有些不稳定。
答案 2 :(得分:1)
通常可以通过前向声明类来减少依赖性。这是一个例子。假设我们有两个先决条件头,parser.h和token.h,定义如下:
parser.h:
class Parser
{
public:
void doFoo();
void doBar();
// ... lots of other stuff
};
token.h:
class Token
{
public:
void doQuux();
void doBaz();
// ... continues for a while
};
现在,有一个“用户,h”使用这两个,而不是写它:
#include "parser.h"
#include "token.h"
void useParserAndToken( Parser &, Token & );
你写了
class Parser;
class Token;
void useParserAndToken( Parser &, Token & );
这样你最终会说有Parser和Token类,但它们的定义方式无关紧要。这样可以加快编译速度。
为了减少依赖关系,通常只能转发声明类。另一方面,复制函数声明没有多大意义。