2010-07-28 2 views
2

У меня проблема следующей циклической зависимости я пытаюсь решить:Ломать циклическую зависимость в C++

typedef std::map<int, my_class> my_map; 

class my_class { 
... 
private: 
    my_map::iterator iter; 
}; 

class otherclass{ 
public: 
    my_map::iterator getIter(); 
private: 
    my_map map; 
}; 

компилятору не нравится это, поскольку my_class не был объявлен до ЬурейеГо.

если я пытаюсь передать, объявить MyClass следующим образом:

class my_class; 

typedef std::map<int, my_class> my_map; 

class my_class { 
... 
private: 
    my_map::iterator iter; 
}; 

class otherclass{ 
public: 
    my_map::iterator getIter(); 
private: 
    my_map map; 
}; 

я получаю «ошибка: опережающее объявление о„my_class“».

Как я могу разбить этот порочный круг?


Извините, но я должен пересмотреть свой вопрос, поскольку я заметил, что мое представление немного ошибочно.

Ниже правильное представление моей проблемы:

class my_container; 

typedef std::map<int, my_container> my_map; 

class my_class { 
... 
private: 
    my_map::iterator iter; 
}; 

class my_container { 
public: 
    my_class a_method(); 
private: 
    vector<my_class> v; 
}; 

class otherclass{ 
public: 
    my_map::iterator a_method(); 
    my_class another_method(); 
    my_container yet_another_method(); 
private: 
    my_map map; 
}; 

К сожалению об этом

+1

Вы можете оставить точное сообщение об ошибке, данное компилятором? – Naveen

+1

Выполнение точной копии приведенного выше кода и удаление «...» из сборки my_class в VS2005 – Patrick

+1

Пересмотренный пример также компилируется с VS2010 даже при выключенном расширении языка. –

ответ

2
class my_class; 

typedef std::map < int, my_class* > my_map; 
         ~~~~~~~~~~ use pointer here! 
+0

Пожалуйста, не используйте указатели. Это просто приведет к утечкам, поскольку вы явно не определяете право собственности на объекты. –

+0

+1, хотя это предполагает, что вы не * хотите * добавив это на карту, чтобы вызвать копию. Это вообще правда. @izex, вам действительно нужно намереваться создать полную копию объекта каждый раз, когда вы кладете его на карту или читаете с карты?Это, как правило, довольно дорого. В стороне, мне очень понравилось shared_ptr <> для этой проблемы: typedef std :: map > my_map; Он просто очищает головную болью управления памятью от использования необработанного указателя здесь. –

0

поставил my_map в качестве члена в my_class, как это:

class my_class { 
public:  typedef std::map<int, my_class> my_map; 
... 
private: 
     my_map::iterator iter; 
}; 

class otherclass{ 
public: 
     my_class::my_map::iterator getIter(); 
private: 
     my_class::my_map map; 
}; 

Если вы не» t хочу всегда использовать my_class::, затем сделать еще один typedef.

0

Вы можете поместить ЬурейеЕ внутри my_class:

class my_class { 
public: 
    typedef std::map<int, my_class> my_map; 
... 
private: 
    my_map::iterator iter; 
}; 

class otherclass{ 
public: 
    my_class::my_map::iterator getIter(); 
private: 
    my_class::my_map map; 
}; 
+0

yep, это должно работать, но, к сожалению, я ошибся, форматируя свой вопрос, и моя ситуация немного сложнее. Пожалуйста, см. Сообщение. – izex

1

Круговой зависимость, как правило, плохо. Можете ли вы немного подумать о своем дизайне? Нужно ли my_class знать, что такое его контейнер?

Если это не практично, вместо итератора в my_map вы могли бы уйти всего лишь с my_container*? У компилятора не будет проблемы с использованием неполного типа для указателя.

+0

Спасибо. Я знаю, что это не тривиально, но в моем случае нужна круговая зависимость. Я действительно решил проблему usin my_container *. – izex

0

Как насчет:

#include <map> 

class my_class;       // forward declare the type. 
typedef std::map<int, my_class> my_map; 

class my_class 
{ 
    private: 
    my_map::iterator iter; 
}; 

class otherclass 
{ 
    public: 
    my_map::iterator getIter(); 
    private: 
    my_map map; 
}; 
Смежные вопросы