头包括和循环依赖关系
headers include and cyclic dependency
我想知道为什么下面的代码不起作用。在b.cpp中,类b使用类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’
您需要使用Forward声明来打破这种循环依赖关系
但是,请注意,一旦转发声明了一个类型,该类型将成为编译器的不完整类型,并且对如何使用不完整类型有限制
这行不通。在头文件中,应该只包含对其他类的引用或指针。然后您可以转发声明A或B,例如:
//===============================================
//file: b.hpp
//===============================================
#ifndef _B_HPP
#define _B_HPP
class A;
class B{
public:
B(A& a);
};
#endif
删除
#include "b.hpp"
来自a.h
,并且只有一个正向声明-假设您在A
:中使用指向B
的指针
//A.hpp
class B; //forward declaration
class A{
public:
A();
// others methods using B here
};
此外:以下划线_
开头的宏名称由标准保留,不应使用。将_B_HPP
替换为简单的B_HPP
。
为什么需要这样的循环#include
?如果你只需要编译器知道一个类的存在(所以它可以是一个参数等),只需像这样向前声明:
class A;
不要循环包含文件。即使有了保护,它们也只会被包含一次,当然,但在编译器到达其定义之前,你仍然会遇到A
的提及,或者在编译器到达定义之前遇到B
的提及。
当b.hpp包含a.hpp时,已经定义了_A_HPP
,因此预编译器忽略文件的内容,因此在B(A a)
行中,编译器不知道a.
如果您确实需要这些include,请尝试将#include "b.hpp"
移动到a.hpp
的末尾(或在b.hpp
的头中声明class A;
)。
在A.hpp中,不要包含B.hpp或调用B方法的内联A实现。
如果需要引用B&
或B*
,请在A.hpp(正向声明)中使用class B;
。
相反,将那些调用B方法的A实现放在A.cpp中,并将B.hpp包含在A.cpp.
相关文章:
- C++GTKMM gui循环依赖关系
- 如何在头文件中声明类模板(由于循环依赖关系)
- 对在不同二进制文件中创建的对象文件的依赖关系
- 使用Bazel构建具有不同编译器/链接器选项的C/C++依赖关系
- OpenVINO - 推理库插件 libMKLDNNPlugin.so 无法解析依赖关系
- 模拟测试中类的依赖关系
- C++模板方法中的循环依赖关系
- 解析正交模块的依赖关系
- 如何在 Mac OS 上安装 boost-mpi 及其对 clang 的依赖关系?
- Wt::D bo 中的循环依赖关系
- 在包含窗口标头时难以解决循环依赖关系问题
- 当依赖关系和依赖关系都是多态时,在哪个继承级别存储依赖关系指针?
- 解决循环依赖关系 c++ 的想法
- C++循环依赖关系,未声明的标识符
- C++ 中的循环依赖关系问题
- 为什么包含需要进一步的依赖关系?
- 使用 cmake 获取外部依赖关系
- CMake 外部和内部静态库的循环依赖关系
- 在没有Xcode的macOS中开发具有依赖关系的应用程序
- "std::shared_ptr"循环依赖关系是如何导致问题的