2012-02-24 5 views
1

Я думаю, что у меня есть проблема с циклической зависимостью и понятия не имею, как ее решить .... Чтобы быть как можно короче: Я кодирую что-то вроде анализатора 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»: это не класс или пространство имен имя

Как решить эту проблему? Спасибо!

+7

Решение не должно быть таким ленивым;) –

+0

@ 500-InternalServerError: :-) Так значит, я должен отделить определения и декларации? Это поможет? – Novellizator

+1

@Tomy: Да, без разделения это практически невозможно. –

ответ

5

То, что вы, вероятно, хотите сделать здесь оставить объявление метода в заголовке, как так

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(); // > 
} 

Это должно решить проблему циклической зависимости вы видите ...

+0

переписал классы, проблема решена. Благодарю. В любом случае, у меня есть последний вопрос: в Parser.h У меня есть одно объявление, которое использует форму [vector

parse();] Как это решить? Я попытался написать «#include» Form.h «» перед классом, но это не помогло ... Наконец, я разрешил его с помощью «class Form»; до класса Parser. Есть ли лучшее решение? Или это единственный? – Novellizator

+0

Я имею в виду это: представьте, что у меня есть другая встроенная функция в Parser.h «void DO() {Form :: DODODO();}« это вызывает ошибку компиляции - как ее разрешить? – Novellizator

+0

Определите 'void DO()' в исходном файле, подобном тому, как 'parse()' определяется в исходном файле в моем ответе выше, и эта проблема также исчезает. Встроенные методы с зависимостями типа (например, 'Parser :: DO()' делают вызов метода, определенного в 'Form'), являются плохими идеями в любом случае ... – hatboyzero

1
  1. Stop определения ваших функций-членов лексического встроенный в заголовки. Определите их в исходных файлах.
  2. Теперь вы можете использовать форвардные объявления, когда они вам нужны (вас здесь нет).
Смежные вопросы