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

发布于 2024-11-28 21:52:39 字数 591 浏览 3 评论 0原文

我使用 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 而不是 include 时,有什么需要注意的隐患吗?

I have eliminated two header inclusions in a translation unit using extern. Is this advisable?

My specific situation: I have a class called ParseTree that accumulates Token*'s. ParseTree* is a private member of Parser.

Initially, I had the following lines in parse_tree.cc.

#include "parser.h"
#include "token.h"

After analyzing my code, I isolated the two functions that actually had external dependencies and replaced the includes with the following:

extern std::ostream& operator<<(std::ostream& out, const Token& t); // @token.h
extern bool hasPriority(const Token* p_tok1, Token* p_tok2); // @parser.h

Both solutions appear to work. Are there any hidden dangers of which I should be aware when selecting extern over include?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

影子的影子 2024-12-05 21:52:39

如果您使用 extern 声明,则在使用该函数的任何地方都会重复声明该函数的原型,这是不必要的重复。有了头文件,如果你想改变原型,只需要改变一处即可。

所以不,当你已经有合适的头文件时,不要使用extern

If you use extern declarations, you're unnecessarily repeating yourself by restating the prototype of the function everywhere you use it. With a header file, if you want to change the prototype, you only need to change it in one place.

So no, don't use extern when you already have a suitable header file.

旧时模样 2024-12-05 21:52:39

这两种解决方案似乎都有效。选择 extern 而不是 include 时是否有什么隐患需要注意?

是的。 API 可能会发生变化,编译器不会为你工作,它会对你不利。

学习如何使用编译器来发挥自己的优势。不,不仅仅是“现在”,我的意思是从长远来看。从长远来看,你会犯愚蠢的错误,而不是当你脑子里的一切都是新鲜的时候。是的,你大脑的记忆在某种程度上是不稳定的。

Both solutions appear to work. Are there any hidden dangers of which I should be aware when selecting extern over include?

Yes. The API may be changing, and the compiler won't work for you, it will work against you.

Learn to use the compiler to your advantage. No, not only "NOW", on the long term I mean. The long term is where you make stupid mistakes, not when there's everything fresh in your head. Yes, your brain's memory is somehow volatile.

审判长 2024-12-05 21:52:39

通常,人们可以通过前向声明类来减少依赖性。这是一个例子。假设我们有两个先决条件标头,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
};

现在,有一个使用这两个的“user,h”,而不是像这样

#include "parser.h"
#include "token.h"

void useParserAndToken( Parser &, Token & );

class Parser;
class Token;

void useParserAndToken( Parser &, Token & );

写 你最终会说存在类 Parser 和 Token,但它们的确切定义方式并不重要。这会导致编译速度更快。

为了减少依赖性,您通常只前向声明类。另一方面,重复函数声明没有多大意义。

Usually one reduces dependencies by forward-declaring classes. Here's an example. Say we have two prerequisite headers, parser.h and token.h, defined as follows:

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
};

Now, having a "user,h" which uses those two, instead of writing it like:

#include "parser.h"
#include "token.h"

void useParserAndToken( Parser &, Token & );

you write

class Parser;
class Token;

void useParserAndToken( Parser &, Token & );

This way you end up saying that there are classes Parser and Token, but how they are defined exactly doesn't matter. This results in faster compiles.

In order to reduce dependencies you usually only forward-declare classes. Duplicating function declarations doesn't make much sense, on the other hand.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文