【问题标题】:cyclic dependency ... how to solve?循环依赖...如何解决?
【发布时间】:2012-03-15 04:38:24
【问题描述】:

我认为我有一个循环依赖问题,不知道如何解决它.... 尽可能短: 我正在编写类似 html 解析器的代码。 我有一个 main.cpp 文件和两个头文件 Parser.h 和 Form.h。 这些头文件保存了整个定义...(我懒得制作相应的.cpp文件...

Form.h 看起来像这样:

//... standard includes like iostream....

#ifndef Form_h_included
#define Form_h_included

#include "Parser.h"
class Form {
public:
    void parse (stringstream& ss) {

        // FIXME: the following like throws compilation error: 'Parser' : is not a class or namespace name
        properties = Parser::parseTagAttributes(ss);

        string tag = Parser::getNextTag(ss);
        while (tag != "/form") {
            continue;
        }
        ss.ignore(); // >
    }
// ....
};
#endif

Parser.h 看起来像这样:

// STL includes
#ifndef Parser_h_included
#define Parser_h_included

#include "Form.h"

using namespace std;

class Parser {
public:
    void setHTML(string html) {
         ss << html;
    }
    vector<Form> parse() {
        vector<Form> forms;

        string tag = Parser::getNextTag(this->ss);
        while(tag != "") {
            while (tag != "form") {
                tag = Parser::getNextTag(this->ss);
            }
            Form f(this->ss);
            forms.push_back(f);
        }
    }
// ...
};
#endif

不知道这是否重要,但我正在 MS Visual Studio Ultimate 2010 中进行构建 它把我扔了 'Parser' : 不是类或命名空间名称

如何解决这个问题? 谢谢!

【问题讨论】:

  • 解决方案:别那么懒惰 ;)
  • @500-InternalServerError: :-) 所以这意味着我必须将定义和声明分开?会有帮助吗?
  • @Tomy:是的,没有分离几乎是不可能的。
  • @LightnessRacesinOrbit 好的,我可能说错了 - 我被教导分开做这件事并不重要,所以我决定不做......我不知道它是做到这一点至关重要......直到现在我只做非常简单的项目,所以我不需要制作单独的文件......
  • @Tomy:这不是“关键”,但它非常明智。这也是原因之一。谁教你“没那么重要”的人太傻了。

标签: c++ dependencies circular-dependency


【解决方案1】:

您可能想要在这里做的是将方法声明留在标题中,像这样

class Form {
public:
    void parse (stringstream& ss);
// ....
};

并像这样在源文件(即 Form.cpp 文件)中定义方法

#include "Form.h"
#include "Parser.h"

void parse (stringstream& ss) {

    properties = Parser::parseTagAttributes(ss);

    string tag = Parser::getNextTag(ss);
    while (tag != "/form") {
        continue;
    }
    ss.ignore(); // >
}

这应该可以解决您看到的循环依赖问题...

【讨论】:

  • 重写了课程,问题解决了。谢谢。无论如何,我还有最后一个问题:在 Parser.h 中,我有一个使用表单的声明 [vector
    parse();] 如何解决这个问题?我试图在上课前写“#include”Form.h“”但没有帮助......最后我用“class Form;”解决了它在 Parser 类之前。有更好的解决方案吗?还是只有这一个?
  • 我的意思是:假设我在 Parser.h 中有另一个内联函数 "void DO() {Form::DODODO();}" 这会引发编译错误 - 如何解决?跨度>
  • 在源文件中定义void DO(),类似于我在上面的答案中在源文件中定义parse(),这个问题也消失了。具有依赖关系的内联方法(即Parser::DO() 调用Form 中定义的方法)无论如何都是一个坏主意......
【解决方案2】:
  1. 停止在标题中以词法方式内联定义您的成员函数。在源文件中定义它们。
  2. 现在您可以在需要时利用前向声明(您不在这里)。

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 2020-11-12
    • 2021-04-26
    • 2011-08-16
    相关资源
    最近更新 更多