[英]Circular dependency with using directive where forward declarations don't work
[英]Circular include dependency/Forward Declarations
循环的所有解决方案都包括依赖关系,我已经在“这种特殊情况”下看到过,不需要完整的类定义,因为“您”仅使用指向该类的指针。
我遇到了此问题,并使用前向声明对其进行了修复。
我想知道当您需要两个类中另一个类的特定定义时您应该怎么做。
另外,为什么使用指向类的指针允许您使用前向声明而不是类定义?
在什么情况下,您需要两个类都预先知道的规范?
一种不可能的情况如下:
class A
{
B m_b;
};
class B
{
A m_a;
};
但这是不可能的,因为类A的大小取决于类B的大小,而类B的大小取决于类A的大小A myA; myA.m_b.m_a.m_b.m_a....
A myA; myA.m_b.m_a.m_b.m_a....
当您尝试构造其中一个时。
如果使用指针,则不需要知道两者的大小。 根据所使用的平台,指针的大小始终相同。 并且该系列消失了,因为需要显式创建堆中的对象。
我想知道当您需要两个类中另一个类的特定定义时您应该怎么做。
这可以通过现代编译器中的前向声明和延迟定义来完成。 许多较早的编译器仅允许使用指针和引用来转发声明的类型。
这是一个人为的示例:
丙型肝炎
class B;
class A
{
public:
int32_t Value;
A(int32_t value) : Value(value) { }
int32_t Add(B b) const;
}
乙型肝炎
#include "A.hpp"
class B
{
public:
int32_t Value;
B(int32_t value) : Value(value) { }
int32_t Sub(A a) const;
}
AB.hpp
#include "A.hpp"
#include "B.hpp"
inline int32_t A::Add(B b) const
{
return this->Value + b.Value;
}
inline int32_t B::Sub(A a) const
{
return this->Value - a.Value;
}
另外,为什么使用指向类的指针允许您使用前向声明而不是类定义?
转发声明只是编译器的名称。 这个概念存在,所以你可以使用还没有被定义的类型。 这是必需的,因为C ++解析代码的方式是从中继承大量C语言的产物。 C ++解析器实际上只是仅向前的文本处理器,它们在#include
和使用宏时会注入文本。 这是一个概念上简单的模型,使早期的C / C ++编译器更易于编写。 将此与C#/ Java进行对比,您仅在其中使用using / import并通过简单的语法在类之间愉快地创建循环依赖关系。
指针实际上只是整数,类似于short
和int
,但具有由语言强制执行的特殊语义和基于CPU体系结构在编译时已知的固定大小。 这使得指针声明对于编译器来说非常简单。
前向声明有利于循环依赖和实现隐藏(这也可以加快编译时间)。 考虑一下pimpl习惯用法 。 没有前向声明,就没有类型安全的方法来隐藏实现细节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.