使用正向参考
Using forward reference
本文关键字:参考 更新时间:2023-10-16
我有一个循环头问题,与这里已经问过的大多数问题不同。我有两个相互依赖的类,但不是成员,所以不要遇到编译器无法计算类大小的问题。所以我可以使用正向声明来打破这个循环。
但是,我不希望客户端必须同时包含这两个头才能使用我的类。标头应该是自包含的,这样用户就不需要意识到这种依赖关系。有办法做到这一点吗?
编辑:棘手的部分是A和B必须只定义标题。
在标题A.hpp 中
#ifndef A_HPP
#define A_HPP
#include "B.hpp"
struct A
{
B foo() { ... }
};
#endif
在标题B.hpp 中
#ifndef B_HPP
#define B_HPP
struct A;
struct B
{
void bar()
{
A a = A();
...
}
};
#endif
在main.cpp 中
#include "B.hpp"
B().bar(); // error: 'a' uses undefined class 'A'
标题B.hpp
#ifndef B_HPP
#define B_HPP
struct A;
struct B
{
void bar();
};
#endif
来源B.cpp
#include "A.hpp"
void B::bar()
{
A a;
}
编辑因此,如果您想要仅头的实现,那么请使用AndreyT解决方案。
如果两个标头都包含要求另一个类型完整的代码,那么在一般情况下,它不可能由自包含标头实现。
在您的特定示例中(太简单而不具有代表性),您可以简单地将定义从B::bar
移动到A.hpp
:
inline void B::bar()
{
A a = A();
...
}
但是,当然,在A.hpp
中定义B
的方法看起来并不是很优雅。
如果B::bar
的"内联性"对您来说很重要,那么"工业"解决方案将涉及将B::bar
的定义放入一个额外的头文件B_aux.hpp
中。当你包括标题时,你应该在包括所有"正常"标题之后包括"辅助"标题,即在main.cpp
中,你会有
#include "A.hpp"
#include "B.hpp"
#include "C.hpp"
...
#include "B_aux.hpp"
...
但这显然不是一种"自给自足"的方法。
只需在B.hpp的底部添加一个#include "A.hpp"
。您仍然会有一个循环include,但现在它不会有任何影响。
通常循环包含是两种类型密切相关的标志,这可能意味着它们是单个组件。如果是这种情况,那么当两种类型都已完全定义时,只需将两个标头合并为组件的单个标头,首先是类型声明,最后是成员函数定义。
相关文章:
- C++错误消息*成员参考.**初学者*
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- 参考资源文件VC++中的$(SolutionDir)
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 为什么在运算符重载时需要参考?
- 使 \page 和 \subpage 参考 doxygen 中的方法文档
- std::shared_ptr 自定义参考计数器
- 英特尔 TBB 程序不会终止,可能会误用参考计数器
- 避免在基于反向范围的for循环实现中悬挂参考
- 通用参考 l 值不复制对象
- 标准::enable_if和通用参考的使用差异
- 标准::积累参考?
- C++丢失了参考
- 我可以有一个 ELI5 作为参考和指针以及何时使用它们吗?
- 矢量的通用参考
- 为什么"fun(i)"被推导出为"fun<int&>"而不是"fun<int>",因为"i"是"int"的类型而不是参考?
- C++17 和静态临时生存期的参考扩展
- C++ 参考:这两个语句有什么区别?
- 如何理解 C++17 标准参考中的 [intro.object]/3? N4659 的
- 是否有必要使用 std::move?这不是已经是一个右值参考了吗?