循环依赖问题LinkedList

时间:2014-11-10 20:34:51

标签: c++ linked-list nodes circular-dependency

问题简介:我正在制作一个程序,使用链接列表跟踪机场的航线。例如,如果数据集是

(Austin - Dallas, Dallas - Houston)

你试图找到一个航班

(Austin - Houston) 

它会计算你需要乘坐飞行路径:

(Austin - Dallas - Houston)

我的解决方案的工作方式(如果我能弄清楚如何做)是我有一个由OuterNode组成的外链表,每个包含一个内部链接的航班列表。 内部链表由InnerNode组成,其中包含指向外部节点(也称为航班目的地)的指针。 理论上,它可以使很多事情更容易迭代,而不必通过字符串继续复制数据。 在我的标题中,太多我的东西需要彼此,并且无法按正确的顺序执行。 (这都在内部列表类的标题中)

struct OuterNode {
    InnerList flights;
    int name;
    OuterNode* next;
};

struct InnerNode {
    OuterNode* dest;
    int price;
    InnerNode* next;
};
class InnerList
{
public:
    InnerList();
    ~InnerList();
    void add(InnerNode*);
private:
    InnerNode* innerhead;
};

基本上是这样的:

OuterNode - 需要InnerList(尚无定义)

InnerNode - 需要OuterNode

InnerList - 需要InnerNode

目前的错误是,当InnerList需要制作OuterNode时,{{1}}不存在。 我该如何解决这个问题,以便一切都能找到它需要的东西? 我是否可以使用模板或其他东西来解决这个问题?

2 个答案:

答案 0 :(得分:0)

您需要使用前向声明。

当编译器只需要知道某个类型存在,但不需要知道它的定义时(就像声明指针时那样),你可以使用前向声明告诉编译器'具有此名称的类型存在':

class InnerNode;
class InnerList
{
public:
    InnerList();
    ~InnerList();
    void add(InnerNode*);
private:
    InnerNode* innerhead;
};

这将编译,因为InnerList不需要了解InnerNode;它只需要知道名为InnerNode的类型存在。

如果您的班级中有类型的实际实例,就像OuterNode的情况一样,前向声明将不起作用。该类必须知道要为该类型分配多少存储空间,因此需要完整定义。

您可以使用前向声明来编译InnerListInnerNode,但是您需要将OuterNode的定义移到InnerList之后,因为它依赖在它被定义。

答案 1 :(得分:0)

  

“我是否可以使用模板或某些东西来解决这个问题?”

无需使用模板,您可以简单地重新构建代码,并为struct InnerNode;

引入前向声明
struct InnerNode;  // << forward declaration 

// Declare class InnerList first
class InnerList {
public:
    InnerList();
    ~InnerList();
    void add(InnerNode*);
private:
    InnerNode* innerhead;
};

struct OuterNode {
    InnerList flights;
    int name;
    OuterNode* next;
};

// Finally declare InnerNode completely
struct InnerNode {
    OuterNode* dest;
    int price;
    InnerNode* next;
};

<强> LIVE DEMO


请注意:

您也可以考虑在OuterNode结构中使用std::list<InnerNode*> flights;甚至std::vector<InnerNode*> flights;成员,而不是制作自己的链接列表结构。
虽然这些解决方案需要通过内存管理正确处理InnerNode的实例,std::list<std::shared_ptr<InnerNode>>std::vector<std::shared_ptr<InnerNode>> 看起来是正确的方式。