C++ C++;头文件中的循环依赖关系

C++ C++;头文件中的循环依赖关系,c++,header-files,circular-dependency,C++,Header Files,Circular Dependency,如果不将A类中的数据成员b1转换为指针/引用,并且不放宽B类中的内联函数要求,是否可以避免以下头文件中的循环依赖 A.h: \ifndef A\u H #定义一个 #include//Required,因为数据成员b1不是指针/引用 甲级{ 公众: b1;//我想保持原样。 国际货币基金组织; }; #恩迪夫 B.h: #ifndef B#H #定义B_H #include//Required,因为f()调用类a的成员函数 B类{ 公众: intf(A&A){returna.m_A;}//我希

如果不将A类中的数据成员b1转换为指针/引用,并且不放宽B类中的内联函数要求,是否可以避免以下头文件中的循环依赖

A.h:

\ifndef A\u H
#定义一个
#include//Required,因为数据成员b1不是指针/引用
甲级{
公众:
b1;//我想保持原样。
国际货币基金组织;
};
#恩迪夫
B.h:

#ifndef B#H
#定义B_H
#include//Required,因为f()调用类a的成员函数
B类{
公众:
intf(A&A){returna.m_A;}//我希望这是一个内联函数。
};
#恩迪夫
…假设main.ccp是:

#include <iostream>
#include <A.h>
#include <B.h>

int main() {
    A a;
    B b;

    std::cout << "Calling b.f(a): " << b.f(a) << std::endl;

    return 0;
}
#包括
#包括
#包括
int main(){
A A;
B B;
std::cout您可以使用:

A.h

#包括
#如果没有
#定义一个
甲级
{
公众:
B b1;
国际货币基金组织;
};
#endif//A_H
B.h

#ifndef B#H
#定义B_H
甲级;
B类
{
公众:
内部财务(A&A);
};
#包括
内联int B::f(A&A)
{
上午返回;
}
#endif//B_H
main.cpp

#include <iostream>
#include <A.h> // these could be in any order
#include <B.h>

int main() 
{
    A a;
    B b;

    std::cout << "Calling b.f(a): " << b.f(a) << std::endl;

    return 0;
}
#包括
#包括//这些可以是任何顺序
#包括
int main()
{
A A;
B B;

std::难道你不能在cpp文件中将函数声明为
内联
吗?你认为
#如果ndef
做了什么?lol,它只会定义一次。@dwcanillas我假设你是在暗示我从类B中删除
#include
,并在那里做一个转发声明。让我们假设我这样做了。然后呢我必须在我希望函数内联的任何地方都包含B.cpp。有没有一种方法不需要这样的重复?目的是将其用作“标题保护”为了避免包含多个标题。如果您建议一个解决方案,请您更清楚一点好吗?文件会被调用,但它不会重新定义标题,这说明了标题保护的目的。因此,在main中,a从main调用,B从a调用,a试图从B调用,但从堆栈调用返回文件可能会被调用,但在前几次之后,它将不再重新定义它。因此,您定义了它,但它不会重新定义它们,不是吗?作为一个补充说明,如何使用正确的继承?a和B如何相互继承。这种技术称为“向前声明”。您让编译器知道该类存在。每一步到目前为止,我一直在使用这种语言,所以我有点担心头保护之外的
#include
,但我明白了重点。不幸的是,摆脱
#include
外部保护的唯一方法是使包装头
a#B.h
(有自己的保护)它包括无保护的
A.h
B.h
,然后在任何地方使用此包装器。为了进一步保护用户不直接包含这些标题,您可以在这些标题中使用
\ifndef
包装器保护宏
A\u B\u h
#include <iostream>
#include <A.h>
#include <B.h>

int main() {
    A a;
    B b;

    std::cout << "Calling b.f(a): " << b.f(a) << std::endl;

    return 0;
}
#include <B.h>
#ifndef A_H
#define A_H

class A 
{
public:
    B b1;
    int m_a;
};

#endif // A_H
#ifndef B_H
#define B_H

class A;

class B 
{
public:
    int f(A &a);
};

#include <A.h>

inline int B::f(A &a)
{
    return a.m_a;
}

#endif // B_H
#include <iostream>
#include <A.h> // these could be in any order
#include <B.h>

int main() 
{
    A a;
    B b;

    std::cout << "Calling b.f(a): " << b.f(a) << std::endl;

    return 0;
}