【问题标题】:C++ Circular Dependency in Header Files头文件中的 C++ 循环依赖
【发布时间】:2015-07-25 06:00:18
【问题描述】:

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

啊哈:

#ifndef A_H
#define A_H
#include <B.h> // Required, as data member b1 is not a pointer/reference

class A {
    public:
        B b1; // I want to keep this as as it is.
        int m_a;
};

#endif

B.h:

#ifndef B_H
#define B_H
#include <A.h> // Required, as f() calls a member function of class A

class B {
    public:
       int f(A &a){return a.m_a;} // I want this to be an inline function.
};

#endif

...假设 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;
}

【问题讨论】:

  • 不能在cpp文件中把函数声明为inline吗?
  • 你认为#ifndef 是做什么的?大声笑,它只会定义一次。
  • @dwcanillas 我假设您暗示我从 class B 中删除 #include &lt;A.h&gt; 并在那里进行前向声明。假设我这样做了。然后我必须包括 B.cpp everywhere 我希望函数被内联。有没有不需要这种重复的方法?
  • @Fallen 目的是将其用作“标题保护”以避免标题的多次包含。如果您提出解决方案,能否说得更清楚些?
  • 文件被调用,但它不会重新定义标题,因此标题保护的目的。因此,在 main 中,A 从 main 调用,B 从 A 调用,A 试图从 B 调用但被踢回,从堆栈调用返回。文件可能会被调用,但在最初的几个之后,它不会再重新定义它了。所以你定义了它,但它不会重新定义它们,不是吗?作为旁注,如何使用适当的继承? A和B如何互相继承。

标签: c++ header-files circular-dependency


【解决方案1】:

你可以用这个:

啊.h

#include <B.h>
#ifndef A_H
#define A_H

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

#endif // A_H

B.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

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

【讨论】:

  • 这种技术称为“前向声明”。您正在让编译器知道该类存在。
  • 到目前为止,我的每一步都用这种语言炸毁了我的脸,所以我对头部后卫之外的#include 有点紧张,但我明白了这一点。
  • 不幸的是,摆脱#include 外部防护的唯一方法是制作包装头A_B.h(带有自己的防护),其中包括无防护A.hB.h订购然后在任何地方使用这个包装器。为了进一步保护用户免于直接包含这些标头,您可以在这些标头中使用#ifndef 包装器保护宏A_B_H#error
猜你喜欢
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 2011-06-16
  • 1970-01-01
相关资源
最近更新 更多