是否存在“双重链接”有用或必要的情况? 头文件? (C++)

发布于 2024-07-20 18:21:22 字数 356 浏览 8 评论 0原文

我使用术语“双链接”,因为我不知道实际的短语是什么,或者是否有一个,但假设您有两个标头,head1.h 和 head2.h,其内容如下:

在 head1.h 中:

#include"head2.h"
//do stuff

在 head2.h 中:

#include"head1.h"
//do stuff

我将其想象为彼此相对放置的两个镜子,因为它并不是真正的无限循环,而是某种将无限带入有限计算机的其他形式(但我离题了)。 关键是,是否有任何情况下使用这个概念或这个概念的变体是有用或必要的? (即:我想 goto 可以用作即兴休息)。

I use the term "double link" because I don't know what the actual phrase is, or if there is one, but assuming you have two headers, head1.h and head2.h, with these contents:

In head1.h:

#include"head2.h"
//do stuff

In head2.h:

#include"head1.h"
//do stuff

I visualise it as two mirrors placed opposite each other, as it's not really an infinite loop, but some other form of getting infinity into a finite computer (but I digress). The point is, is there any situation where it would be useful or necessary to use this concept, or a variation of this concept? (ie: I suppose goto could be used as an improv break).

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

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

发布评论

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

评论(4

鸢与 2024-07-27 18:21:22

通常,标头具有预处理器语句,以防止此类事情导致无限递归:

#ifndef MY_FILE_H
#define MY_FILE_H

//do stuff

#endif

即使有这种保护,相互包含通常也是一个坏主意。

Usually, headers have preprocessor statements to prevent precisely this kind of thing from causing an infinite recursion:

#ifndef MY_FILE_H
#define MY_FILE_H

//do stuff

#endif

Even with that protection, mutual includes are usually a bad idea.

零度° 2024-07-27 18:21:22

这是一个“循环包含”,不,这不是一件可取的事情。 你的 goto 没有帮助,因为 goto 是程序执行的一部分,而 #includes 在编译的预处理阶段被解释。

通常的事情是让你的头文件具有这样的结构,

#ifndef FOO_H
#define FOO_H
... rest of the include file here
#endif

这样他们就不会尝试两次定义相同的东西。

如果您尝试一下,会发生以下情况:

bash $ gcc crecursive.c 文件中
包含在 bh.h:1,

<块引用>

 来自 ah.h:1,   
              来自 bh.h:1,   
              来自 ah.h:1,    
  

...省略了很多行

 来自 ah.h:1,    
              来自 crecursive.c:2: ah.h:1:16: 错误:#include 嵌套太深     
  

重击$

That's a "cyclic include" and no, it's not a desirable thing to do. your goto wouldn't help, because gotos are part of the program execution, while the #includes are interpreted during the preprocessing phase of compiling.

The usual thing is to make your header files have a structure like

#ifndef FOO_H
#define FOO_H
... rest of the include file here
#endif

so they don't attempt to define the same stuff twice.

Should you try it, here's what happens:

bash $ gcc crecursive.c In file
included from bh.h:1,

            from ah.h:1,  
            from bh.h:1,  
            from ah.h:1,   

... many lines omitted

            from ah.h:1,   
            from crecursive.c:2: ah.h:1:16: error: #include nested too deeply    

bash $

桃扇骨 2024-07-27 18:21:22

避免这种情况的通常方法是使用空的类声明。

//head1.h

class Foo;

class Bar {
public:
   Bar(Foo* f) : foo(f) {}
private:
   Foo* foo;
};

// head2.h

class Bar;

class Foo {
public:
    void func(Bar* bar); 
};

当一个头文件创建了许多需要在彼此之前声明的类时,您通常会得到一个像 .

//fwd.h

class Bar;
class Foo;

// head1.h

#include "fwd.h"

class Foo { ....

// head2.h

#include "fwd.h"

class Bar { ....

The usual way to avoid this is with empty class declarations.

//head1.h

class Foo;

class Bar {
public:
   Bar(Foo* f) : foo(f) {}
private:
   Foo* foo;
};

// head2.h

class Bar;

class Foo {
public:
    void func(Bar* bar); 
};

When a header file creates a lot of classes that need to be declared before one another you usually end up with an include file like .

//fwd.h

class Bar;
class Foo;

// head1.h

#include "fwd.h"

class Foo { ....

// head2.h

#include "fwd.h"

class Bar { ....
风透绣罗衣 2024-07-27 18:21:22

我将其想象为放置的两个镜子
彼此对立,因为事实并非如此
无限循环

你想象错了。 ;)
请记住,#include 只不过是复制/粘贴,它发生在程序编译之前。 所以你设置的是编译期间的无限循环。 编译器读取 head1.h,它以 #include "head2.h" 开头。 因此它插入 head2.h 并继续解析它,但它以 #include "head1.h" 开头,所以我们必须包含它,依此类推。

通常,您可以使用包含防护来防止编译器陷入无限循环。

关键是,这是在程序编译之前(当然是在执行之前)作为纯文本处理发生的,因此它并不是真正可以用于任何建设性的东西,除非复制/粘贴无限数量的times 是您心目中的欢乐时光。

I visualise it as two mirros placed
opposie each other, as it's not really
an infinite loop

You visualize wrong. ;)
Keep in mind that #include is nothing more than copy/paste, and it happens before your program is compiled. So what you've set up is an infinite loop during compilation. The compiler reads head1.h, which starts with #include "head2.h". So it inserts head2.h and continues parsing that, but it starts with #include "head1.h", so we have to include that, and so on.

You usually have include guards to prevent this from putting the compiler into an infinite loop.

The key is that this happens as plain text processing before the program is compiled, and certainly before it is executed, so it's not really something you can use for anything constructive, unless copy/pasting an infinite number of times is your idea of a fun time.

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