标题包括和循环依赖

时间:2012-01-25 20:25:28

标签: c++ header dependencies

我想知道为什么下面的代码不起作用。 在b.cpp中,类B使用类A,但它失败,因为找不到类A的声明。 但是,之前包含a.hpp。为什么#include“a.hpp”在这里不起作用?

感谢您的帮助!

//===============================================
//file: a.hpp
//===============================================
#ifndef _A_HPP
#define _A_HPP

#include "b.hpp"

class A{
    public:
        A();
        // others methods using B here
};

#endif


//===============================================
//file: a.cpp
//===============================================
#include "a.hpp"

A::A(){}


//===============================================
//file: b.hpp
//===============================================
#ifndef _B_HPP
#define _B_HPP

#include "a.hpp"

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

#endif
//===============================================
//file: b.cpp
//===============================================
#include "b.hpp"

B::B(A a){}



SHELL$ g++ -c a.cpp
In file included from a.hpp:7,
                 from a.cpp:4:
b.hpp:11: error: expected ‘)’ before ‘a’

6 个答案:

答案 0 :(得分:2)

您需要使用 Forward declarations 来打破这种循环依赖 但请注意,一旦转发声明类型,该类型将成为编译器的不完整类型,并且对如何使用不完整类型有限制

答案 1 :(得分:1)

这不起作用。在您的头文件中,您应该只包含对其他类的引用或指针。然后你可以转发声明A或B,例如:

//===============================================
//file: b.hpp
//===============================================
#ifndef _B_HPP
#define _B_HPP

class A;

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

#endif

答案 2 :(得分:0)

删除

#include "b.hpp"
来自a.h

并且只有前向声明 - 假设您使用指向BA的指针:

//A.hpp

class B; //forward declaration

class A{
    public:
        A();
        // others methods using B here
};

另外:以下划线_开头的宏名称由标准保留,不应使用。仅使用_B_HPP替换B_HPP

答案 3 :(得分:0)

为什么需要这样的循环#include?如果你只需要编译器知道一个类存在(所以它可以是一个参数等等),只需向前声明它如下:

class A;

不要循环包含文件。即使有了守卫,他们也只会被包含一次,当然,但是在编译器达到其定义或提及{{1}之前,你仍然会提到A。在编译器达到其定义之前。

答案 4 :(得分:0)

当b.hpp包含a.hpp时,_A_HPP已经定义,因此预编译器会忽略文件的内容,所以在B(A a)行中,编译器不知道甲

如果您确实需要这些内容,请尝试将#include "b.hpp"移至a.hpp的末尾(或在class A;的头部声明b.hpp)。

答案 5 :(得分:0)

在A.hpp中,不要包含调用B方法的B.hpp或内联A实现。

如果您需要引用class B;B&,请在A.hpp中使用B*(转发声明)。

相反,将那些在A.cpp中调用B方法的A实现放在A.cpp中包含B.hpp。