是否建议使用extern来避免头依赖?

时间:2011-08-11 04:59:54

标签: c++ coding-style include extern

我在使用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时,我是否应该注意隐藏的危险?

3 个答案:

答案 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类,但它们的定义方式无关紧要。这样可以加快编译速度。

为了减少依赖关系,通常只能转发声明类。另一方面,复制函数声明没有多大意义。