我想知道为什么下面的代码不起作用。 在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’
答案 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
的并且只有前向声明 - 假设您使用指向B
中A
的指针:
//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。