Всем привет!
Нужно сделать следующее:
Имеется несколько экземпляров класса А.
Класс А может собержать список экземпляров класса В. Как зная В определить получить ссылку на А, который этот В держит в списке?
Проблема в том, что если класс А описывается в файле "А.h", а класс В в "В.h", то компилятор не позволяет чтобы они ссылались друг на друга.
Какие существуют методы, правильные пути решения данной задачи?
Здравствуйте, Andrewsha, Вы писали:
A>Проблема в том, что если класс А описывается в файле "А.h", а класс В в "В.h", то компилятор не позволяет чтобы они ссылались друг на друга.
А как же forward declarations?
//a.hclass B;
class A
{
...
B* pB;
};
//b.hclass A;
class B
{
...
A* pA;
};
Здравствуйте, Bell, Вы писали:
B>А как же forward declarations?
Ну чайник я, чайник
Все классно работает . Но в реале мне надо:
//a.hclass A
{
...
BB* pB;
};
typedef A AA;
//b.hclass B
{
...
AA* pA;
};
typedef B BB;
Так не прокатывает, потому что forward declaration для классов а ВВ или АА не классы...Как быть? Видимо надо typedef-ить в модулях, где собираюсь использовать новый тип. Просто тут не очень красиво получается, если в нескольких модулях хочу использовать, то придется typedef-ить несколько раз.
Re: Классы ссылающиеся друг на друга.
От:
Аноним
Дата:
22.11.02 09:39
Оценка:
Здравствуйте, Andrewsha, Вы писали:
A>Всем привет! A>Нужно сделать следующее: A>Имеется несколько экземпляров класса А. A>Класс А может собержать список экземпляров класса В. A>Как зная В определить получить ссылку на А, который этот В держит в списке?
A>Проблема в том, что если класс А описывается в файле "А.h", а класс В в "В.h", то компилятор не позволяет чтобы они ссылались друг на друга. A>Какие существуют методы, правильные пути решения данной задачи?
Здравствуйте, Andrewsha, Вы писали:
А>>А ЗАЧЕМ ЭТО ВООБЩЕ НАДО? A>Чтобы зная В быстро получить ссылку на А, который этот В держит в списке.
И почему это не может быть глобальная функция-друг обоих классов?
Кстати на счет списка. Структура данных выбирается исходя из контекста ее использования. Если у тебя часто происходит удаление и вставка, а поиск или другой какой запрос — редко, выбирай однозначно list. Если чаще приходится искать — массив (vector), а лучше дерево какое-нибудь. Я не большой знаток STL и всяких boost'ов, но наверняка там что-либо подобное имеется.
З.Ы. Так как ты новичок, настоятельно рекомендую ознакомится с правилами и системой оценок на сайте. Если человек тебе помог, то грех его не поблогадарить, хотя бы словами. Хотя словами иногда даже приятнее.
А> Я это понял, просто мне интересно знать с точки зрения проэктирования
А>class B А>{ А>public: А>B(); А>~B(); А>};
А>class A А>{ А>private: А>list<B> list_of_B; А>public: А>A(); А>... А>~A(); А>}
А>Зачем list_of_B знать об A. Помоему с точки зрения инкапсуляции данных даже это не совсем правильно, или все же что то я не правильно понял...
Да, все правильно изложено. Только теперь допустим, что известен В, как получить А, у которого этот В в списке? Или ты имеешь ввиду ситуацию, когда это может понадобиться? Мол изначально что-то неправильно спроектированно, поскольку возникла такая необходимость...?
А>И почему это не может быть глобальная функция-друг обоих классов?
Надо посмотреть че это за зверь Просто щас не понимаю о чем речь
А>Кстати на счет списка. Структура данных выбирается исходя из контекста ее использования. Если у тебя часто происходит удаление и вставка, а поиск или другой какой запрос — редко, выбирай однозначно list. Если чаще приходится искать — массив (vector), а лучше дерево какое-нибудь. Я не большой знаток STL и всяких boost'ов, но наверняка там что-либо подобное имеется.
А>З.Ы. Так как ты новичок, настоятельно рекомендую ознакомится с правилами и системой оценок на сайте. Если человек тебе помог, то грех его не поблогадарить, хотя бы словами. Хотя словами иногда даже приятнее.
Реальное спасибо за оперативные ответы!!!
Re[5]: Классы ссылающиеся друг на друга.
От:
Аноним
Дата:
22.11.02 10:04
Оценка:
Здравствуйте, Andrewsha, Вы писали:
А>> Я это понял, просто мне интересно знать с точки зрения проэктирования
А>>class B А>>{ А>>public: А>>B(); А>>~B(); А>>};
А>>class A А>>{ А>>private: А>>list<B> list_of_B; А>>public: А>>A(); А>>... А>>~A(); А>>}
А>>Зачем list_of_B знать об A. Помоему с точки зрения инкапсуляции данных даже это не совсем правильно, или все же что то я не правильно понял... A>Да, все правильно изложено. Только теперь допустим, что известен В, как получить А, у которого этот В в списке? Или ты имеешь ввиду ситуацию, когда это может понадобиться?
ДА
Мол изначально что-то неправильно спроектированно, поскольку возникла такая необходимость...?
Здравствуйте, Andrewsha, Вы писали:
А>>И почему это не может быть глобальная функция-друг обоих классов? A>Надо посмотреть че это за зверь Просто щас не понимаю о чем речь
[]
Можно поступить двумя способами
class A;
class B
{
public:
bool is_b_in_a(A& a);
};
class A
{
protected:
list<B*> list_of_b;
public:
void Add(B* b)
{
list_of_b.push_back(b);
}
bool is_b_in_list(B* b)
{
list<B*>::iterator it = find(list_of_b.begin(),list_of_b.end(),b);
return it != list_of_b.end();
}
friend bool B::is_b_in_a(A&);
};
bool B::is_b_in_a(A& a)
{
list<B*>::iterator it = find(a.list_of_b.begin(),a.list_of_b.end(),this);
return it != a.list_of_b.end();
}
int main()
{
B b1,b2,b3,b4;
A a1;
a1.Add(&b1);
a1.Add(&b2);
a1.Add(&b3);
cout << a1.is_b_in_list(&b2) << endl;
cout << b4.is_b_in_a(a1) << endl;
getch();
return 0;
}
Т.е. либо из B проверять принадлежность к А, либо из А проверять принадлежность к нему В. Пример для vector'а приктически отличатся ничем не будет.
А>>>И почему это не может быть глобальная функция-друг обоих классов?
[]
Спасибо за наглядный пример! А>Т.е. либо из B проверять принадлежность к А, либо из А проверять принадлежность к нему В. Пример для vector'а приктически отличатся ничем не будет.
Понятно, толкьо ведь можно в В просто хранить указатель на А, который этот В держит в списке.
К вопросу о typedef:
//a.hclass A
{ ...
BB* pB;
};
typedef A AA;
//b.hclass B
{ ...
AA* pA;
};
typedef B BB;
Так не прокатывает, потому что forward declaration для классов, а ВВ или АА не классы...Как быть? Видимо надо typedef-ить в модулях, где собираюсь использовать новый тип. Просто тут не очень красиво получается, если в нескольких модулях хочу использовать, то придется typedef-ить несколько раз.
У меня был тоже пример. Хорошо, вот пример из моей практики:
class Object
{
public:
virtual ~Object() {}
virtual void draw(Context &) = 0;
};
// корабль
//class Ship : public Object
{
public:
};
class Order;
// позиция в ордере - посредник по сути между ордером и кораблем
//class OrderPosition : public Ship
{
public:
OrderPosition(Order* order, double distance, double couse_angle)
: _owner(order), _ship(0), _distance(distance), _cours_eangle(0)
{
}
void draw(Context &c)
{
_ship->draw(c);
}
private:
Order* _owner; // он мне нужен, поскольку позиция не обладает информацией о тот кто является уравнителем, какой целевой курс - это информация более высокого уровня
Ship* _ship;
double _distance;
double _course_angle;
};
// ордер - группа кораблей (каждый корабль имеет строго регламентированный порядок)
//class Order : public Object
{
public:
...
};
[]
A>Так не прокатывает, потому что forward declaration для классов, а ВВ или АА не классы...Как быть? Видимо надо typedef-ить в модулях, где собираюсь использовать новый тип. Просто тут не очень красиво получается, если в нескольких модулях хочу использовать, то придется typedef-ить несколько раз.
Зачем несколько раз?
//b.hclass A;
typedef A AAA;
class B{
//use AAA
};
class B;
typedef B BBB;
//a.hclass A{
//use BBB
};