【问题标题】:Mutual Import C++相互导入 C++
【发布时间】:2015-05-24 16:23:46
【问题描述】:

我知道这是一个反复出现的问题,但到目前为止,我基本上只看到了“如果你有相互导入,那么你做错了什么”的答案。

这就是为什么我有更多的一般理解问题而不是与某些特定代码相关的问题。

好的,举个例子。假设我有一个动态自动机的数据结构。自动机的状态是具有“转换”属性的结构。 “transitions”是一个动态链表。列表元素是具有 State 对象属性的结构...

所以:

// state.h
#include "transitionList.h"

State{
    TransitionList transitions; // all transitions going out from this state
}

// tranistion.h
#include "state.h"

Transition{
    Transition* next_transition; // the next transition in the TransitionList
    State* successor; // a pointer to the next state in the automaton
}


// transitionList.h
#include "tranisiton.h"

TransitionList{
    // *code* class for a linked list of transitions
}

所以我们有 state.h -> transistion.h -> transitionList.h -> state.h -> ...

这显然是循环的……但概念上的错误在哪里?从正式的角度来看,我不认为这是一个糟糕的布局。

请赐教:)

【问题讨论】:

  • 那不是有效的 C++ 代码。
  • 是的,它应该是更多的伪代码。
  • 也许this 会有所帮助。

标签: c++ include circular-dependency


【解决方案1】:

从概念上讲,这很好。它只是在物理上不起作用,因为 C++ 没有物理模块系统。 #include 指令只是插入包含文件的副本,因此循环包含将产生无限长度的源流。

您需要按特定顺序向编译器提供类,以便它可以编译,这种组合称为“翻译单元”。

如果你有一个类持有指向另一个尚未完全声明的类的指针,你必须“前向声明”它:

class State;

这个技巧允许一个类头不需要包含它持有一个指针的东西的完整定义,并打破循环。

【讨论】:

  • 谢谢!我不知何故认为这只有在两个类共享同一个文件时才有效。但仅此一项就可以防止嵌套导入吗?还是我还需要#ifndef 逻辑?
  • 将标头包装在预处理器 guff 中以确保多重包含的安全性是一种很好的做法,因为否则您未来的客户端代码必须小心它包含事物的顺序。为每个.h 文件创建一个.cpp 文件是个好主意,这样.cpp 文件的第一行就包含.h 文件(即使这就是它所包含的全部内容),因为这证明@可以先包含 987654327@ 文件,因此这会测试每个标头的独立“可包含性”。
  • 还要注意(因为 C++ 没有物理模块系统)源文件之间的边界对语言来说并不重要。预处理器将文件(通过#include)连接到一个流中,编译器并不关心源的来源。
  • 谢谢。将不得不咀嚼一下。
猜你喜欢
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 2017-11-16
  • 2014-08-22
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多