在C ++中包含对方的标题 [英] Headers Including Each Other in C++

查看:100
本文介绍了在C ++中包含对方的标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个C ++新手,但我不能在这里找到这个(很可能是平凡的)问题的答案。我有一些麻烦编译一些代码,其中两个类包括对方。首先,我的#include语句应该在我的宏内部还是外部?在实践中,这似乎没有关系。然而,在这种特殊情况下,我有麻烦。将#include语句放在宏之外会导致编译器递归,并给我#include嵌套太深的错误。这似乎对我有意义,因为在#include被调用之前,没有一个类已经被完全定义。但是,奇怪的是,当我试图把它们放在里面,我无法声明一个类的类,因为它不被识别。这里是,实质上,我想要编译:



Ah

  #ifndef A_H_ 
#define A_H_

#includeBh

A类
{
私人:
B b;

public:
A():b(* this){}
};

#endif / * A_H _ * /

Bh

  #ifndef B_H_ 
#define B_H_

#includeAh

class B
{
private:
A&一个;

public:
B(A& a):a(a){}
};

#endif / * B_H _ * /

main.cpp

  #includeAh

int main()
{
A a;
}



如果有区别,我使用g ++ 4.3.2。 p>

为了清楚,一般来说,#include语句应该在哪里?我总是看到他们走出宏的外面,但我描述的情况清楚似乎打破了这个原则。感谢任何帮助者提前!

解决方案

由宏我假设你的意思是#ifndef include包括卫兵?
如果是这样,#includes肯定会进去。这是包含守卫存在的主要原因之一,因为否则你很容易结束一个无限递归,你注意到。



无论如何,问题是,你使用A和B类(在其他类中),它们还没有被声明。看看#includes处理完毕后代码的样子:

  //#includeAhstart 
#ifndef A_H_
#define A_H_

//#includeBhstart
#ifndef B_H_
#define B_H_

/ /#includeAhstart
#ifndef A_H_ // A_H_已经定义,所以文件的内容在这一点被跳过
#endif / * A_H _ * /

//#includeAhend

class B
{
private:
A&一个;

public:
B(A& a):a(a){}
};

#endif / * B_H _ * /

//#includeBhend

A类
{
private:
B b;

public:
A():b(* this){}
};

#endif / * A_H _ * /
//#includeAhend

int main()
{
A a ;
}

现在阅读代码。 B是编译器遇到的第一个类,它包括一个 A& 成员。什么是 A ?编译器没有遇到 A 的任何定义,因此它发出错误。



解决方案是在B的定义之前的某一点,添加一行 class A;



这给编译器提供必要的信息,A是一个类。我们还不知道还有什么,但由于B只需要包括一个参考,这是足够好的。在A的定义中,我们需要一个类型B的成员(不是一个引用),所以这里B的整个定义必须是可见的。幸运的是,它是。


I'm a C++ newbie, but I wasn't able to find the answer to this (most likely trivial) question online. I am having some trouble compiling some code where two classes include each other. To begin, should my #include statements go inside or outside of my macros? In practice, this hasn't seemed to matter. However, in this particular case, I am having trouble. Putting the #include statements outside of the macros causes the compiler to recurse and gives me "#include nested too deeply" errors. This seems to makes sense to me since neither class has been fully defined before #include has been invoked. However, strangely, when I try to put them inside, I am unable to declare a type of one of the classes, for it is not recognized. Here is, in essence, what I'm trying to compile:

A.h

#ifndef A_H_
#define A_H_

#include "B.h"

class A
{
    private:
        B b;

    public:
        A() : b(*this) {}
};

#endif /*A_H_*/

B.h

#ifndef B_H_
#define B_H_

#include "A.h"

class B
{
    private:
            A& a;

    public:
        B(A& a) : a(a) {}
 };

#endif /*B_H_*/

main.cpp

#include "A.h"

int main()
{
    A a;
}

If it makes a difference, I am using g++ 4.3.2.

And just to be clear, in general, where should #include statements go? I have always seen them go outside of the macros, but the scenario I described clearly seems to break this principle. Thanks to any helpers in advance! Please allow me to clarify my intent if I have made any silly mistakes!

解决方案

By "the macros" I assume you mean the #ifndef include guards? If so, #includes should definitely go inside. This is one of the major reasons why include guards exists, because otherwise you easily end up with an infinite recursion as you noticed.

Anyway, the problem is that at the time you use the A and B classes (inside the other class), they have not yet been declared. Look at what the code looks like after the #includes have been processed:

//#include "A.h" start
#ifndef A_H_
#define A_H_

//#include "B.h" start
#ifndef B_H_
#define B_H_

//#include "A.h" start
#ifndef A_H_ // A_H_ is already defined, so the contents of the file are skipped at this point
#endif /*A_H_*/

//#include "A.h" end

class B
{
    private:
            A& a;

    public:
            B(A& a) : a(a) {}
 };

#endif /*B_H_*/

//#include "B.h" end

class A
{
    private:
            B b;

    public:
            A() : b(*this) {}
};

#endif /*A_H_*/
//#include "A.h" end

int main()
{
    A a;
}

Now read the code. B is the first class the compiler encounters, and it includes an A& member. What is A? The compiler hasn't encountered any definition of A yet, so it issues an error.

The solution is to make a forward declaration of A. At some point before the definition of B, add a line class A;

This gives the compiler the necessary information, that A is a class. We don't know anything else about it yet, but since B only needs to include a reference to it, this is good enough. In the definition of A, we need a member of type B (not a reference), so here the entire definition of B has to be visible. Which it is, luckily.

这篇关于在C ++中包含对方的标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆