The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Зацикливание классов."
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Зацикливание классов."
Сообщение от David emailИскать по авторуВ закладки on 29-Мрт-02, 13:03  (MSK)
Заранее извиняюсь, если вопрос покажется слишком ламерским.
Есть два класса, зацикленных друг на друге и объявленных в разных файлах:
<<<x.h>>>
#include "y.h"
class y;
class x {
public:
  x(): yobj(*this) {}
private:
  y yobj;
};
<<<y.h>>>
#include "x.h"
class x;
class y {
public:
  y(x& xx): xobj(&xx) {}
private:
  x* xobj;
};
На это дело компилер выдаёт такую ругань:
In file included from y.h:5, from y.cpp:2:
x.h:18: field `yobj' has incomplete type.
Объясните, пожалуйста, что ему, собственно, надо. Я предполагаю, что, скорее всего от этого можно избавиться, если впихнуть объявления классов в один файл, но дело в том, что реально классов гораздо больше и они гораздо сложнее, чем в этом примере, и этого очень желательно избежать.
Заранее спасибо. Только не сильно ругайтесь :).
  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "RE: Зацикливание классов."
Сообщение от Арлекин Искать по авторуВ закладки on 29-Мрт-02, 13:31  (MSK)
ТАК "лучше не делать". Ты пытаешься использовать С++ как С. Увы, но это разные языки, хоть и вырос первый из второго. В лучшем случае ты просто запутаешься - при правильной иерархии классов два класса не могут одновременно быть и родителем и дитем между собой (в плюсах есть понятие "Множественное наследование"- когда классы могут быть родителями или/и детьми). Дети видят и могут юзать на прямую всё что у папы protected ( ну и public ессно ). Есть достаточно мощный механизм виртуальных функций - когда каждый ребенок может переопределить ее (функции) сигнатуру.
ИМХО, твои проблемы в неправильной идеологии классов проекта. Самое простое - купить БИБЛИЮ ( 3-е издание "Страуса", на русском уже есть, стоит ~500 р. ) и почитать. Туго по-началу, но потом легко будет. Ну и переделывать придется.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Здесь наследования и близко нет."
Сообщение от David emailИскать по авторуВ закладки on 29-Мрт-02, 20:58  (MSK)
>два класса не могут
>одновременно быть и родителем и
>дитем между собой
Так причём тут наследование? Классы x и y не состоят ни в каких родственных связях. Они просто юзают друг друга. Это достаточно типичный случай, например, когда список содержит элементы определённого класса и каждый элемент содержит ссылку на список, к которому принадлежит. В моём конкретном случае класс x является как бы глобальным центральным управляющим узлом, в котором содержатся объекты (y), выполняющие конкретные функции. Для того, чтобы этим объектам взаимодействовать друг с другом, я им передаю ссылку на x, чтобы метод объекта класса y мог обратиться к объекту x.z таким образом: xobj->z
>Самое простое -
>купить БИБЛИЮ ( 3-е издание
>"Страуса", на русском уже есть,
>стоит ~500 р. ) и
>почитать. Туго по-началу, но потом
>легко будет. Ну и переделывать
>придется.
А это не спорю. Как только деньги появятся, обязательно куплю, хотя C++ в теории я знаю неплохо. Проблема с практикой.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "RE: Здесь наследования и близко нет."
Сообщение от XMan emailИскать по авторуВ закладки on 29-Мрт-02, 22:22  (MSK)
Короче, он тебе говорит, что ты пытаешься пользовать класс, который уже есть, но еще не полностью определен. И он прав. Смотрим сами:

Определяется класс A, в котором (непосредственно в определении) имеется ссылка на класс B. Нет проблем - идем для начала определять класс B. Находим и видим, что в нем (тоже в определении) имеется ссылка на класс A, который еще не определен (он только в процессе). Что мы будем делать ? Первый вариант - идти определять класс A. И так в цикле, пока памяти на машине хватит, а потом свалимся. Компилер пошел по второму пути :))

Я вижу 2 выхода:
1. Раскидать классы по другому;
2. Вынести вызовы соседа из определения класса (*.h) в код конструктора/метода класса (*.cpp) и потом просто в каждом файле *.cpp вставить соответствующие #include

PS. Или я чего-то не понимаю ?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "RE:Хочу добавить."
Сообщение от Арлекин Искать по авторуВ закладки on 30-Мрт-02, 11:20  (MSK)
Во-первых:
Если классы взаимодействуют между собой так, что им нужна только часть функциональности друг друга, обычно делается базовый класс ( или они оба будут предками - не принципиально )исключительно для работы с общей областью. Например есть классы ШКАФ и СТОЛ. Кроме того что они могут быть оба деревянными, их оба можно собирать используя ключ на 12. В таком случае "сборщик мебели" должен быть отдельным классом, и крутить гайки где угодно - и в ШКАФ и в СТОЛ. И все гайки и ключ должны быть у сборщика, а не перетаскиваться из ШКАФ в СТОЛ и назад. А если классы отличаются только типом данных - прямая дорога в шаблоны, хотя я ниразу не построил модель данных в них нуждающуюся.
Во-вторых:
Я плохо понимаю что такое "знать ЯП в теории". Но не суть - дело не в том, что в твоей задаче нет наследования, а в том, что ты НЕПРАВИЛЬНО организовал структуру классов и с точки зрения идеологии и с точки зрения подхода. Например - по возможности ВСЕГДА НАДО выносить тела функций ( ну кроме inline и совсем уж маленьких ) в файл .[cc,cpp].
В-третьих:
Наследование как папа/дите вещь совершенно не обязательная - сделай базовый класс Tools который будет иметь ТОЛЬКО функции сборки мебели. Тоже наследование, своеобразное правда. Именно в этом случае (ты писАл, что работал в винде) показательно было бы разобрать структуру классов какого-нибудь MFC-приложения в MSVC ( для других целей он плохо подходит ).

ЗЫЖ Когда я начинал юзать плюса я налетал на теже грабли - через это все проходят. Дело не в том, что кто-то не умеет "мыслить на уровне объектов", а в том, что ПРИМЕНИТЬ это умение к С++ можно только после приличной практики. Это как пользоваться const вместо #define - "сначала боишься, потом гордишься" :-)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "RE: Здесь наследования и близко нет."
Сообщение от Арлекин Искать по авторуВ закладки on 30-Мрт-02, 11:33  (MSK)
...
В моём конкретном случае класс x является как бы глобальным центральным управляющим узлом, в котором содержатся объекты (y), выполняющие конкретные функции. Для того, чтобы этим объектам взаимодействовать друг с другом, я им передаю ссылку на x, чтобы метод объекта класса y мог обратиться к объекту x.z таким образом: xobj->z
...
Ага - "нет наследования". Твои Y derived от virtual Х и тогда все protected члены Х доступны НАПРЯМУЮ в любом Y от одного Х, инициализированного последним Y.
#include "class_x.h"
class Y: virtual {public|private|protected} X
{
...
}
Это если кол-во Y известно заранее и инициализируется одновременно. Если это все происходит динамически - Х не виртуальный, но каждый Х есть derived от абстрактного класса Z.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "Всё заработало"
Сообщение от David emailИскать по авторуВ закладки on 30-Мрт-02, 15:18  (MSK)
Всё заработало когда я заменил экземпляр yobj на ссылку *yobj и инициализировал её в конструкторе с помощью new. Видимо для ссылок подходит и неполное определение класса. Так что большое спасибо за попощь.
2 Арлекин: Я тоже сторонник ГРАМОТНОГО программирования, и мне приятно общаться с человеком, который думает так же. Не хочется спорить по поводу того, нужно тут делать наследование или нет, потому что мы находимся в неравных условиях, т.к. я знаю задачу, а ты нет. В общем - спасибо.
  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру