Что лучший способ состоит в том, чтобы иметь дело с созависимыми классами в C++?

Скажите, что у меня есть нечто класса с объектом панели класса как участник

class foo
{
    bar m_bar;
};

Теперь предположите потребности панели отслеживать нечто, которое владеет им

class bar
{
    foo * m_pfoo;
}

Эти две ссылки классов друг друга и без предописания, не скомпилирует. Так добавляя эту строку, прежде чем объявление нечто решает ту проблему

class bar;

Теперь, вот проблема - при записи заголовочных файлов, каждый заголовок зависит от другого: foo.h нужны определения в bar.h и наоборот. Каков надлежащий способ иметь дело с этим?

10
задан Nathan Osman 27 January 2010 в 00:18
поделиться

4 ответа

Вам нужно перенести весь членский доступ из заголовка и в исходные файлы.

Таким образом, вы можете переместить объявления ваших классов в заголовке и определить их в foo:

// foo.h
class bar;

class foo {
    bar * m_pbar;
}

// bar.h
class foo;
class bar {
    foo * parent;
}

Это позволит вам работать - вы просто не можете поместить определения, требующие информации о членах в ваш заголовок - переместите их в .cpp-файл. Файлы .cpp могут включать как foo.h, так и bar.h:

// Foo.cpp
#include "foo.h"
#Include "bar.h"

void foo::some_method() {
     this->m_pbar->do_something(); // Legal, now, since both headers have been included
}
24
ответ дан 3 December 2019 в 15:51
поделиться

Если вы используете 0,9 бета-версию Cocos2D, он имеет действительно простое обнаружение касания для Cocosnodes. Настоящая красота этого нового обнаружения состоит в том, что она хорошо справляется с несколькими сенсорными отслеживанием.

Пример этого можно найти здесь

http://code.google.com/p/cocos2d-iphone/source/browse/#svn/trunk/tests/toushestest

-121--2790240-

Я полагаю, что в одном случае - сделать абстрактные интерфейсные классы без членов. Затем подкласс FOO и BAR из этих интерфейсных классов.

E.g.:

class FooInterface
{
   // methods here
}

class BarInterface
{
   // methods here
}

class Foo : public FooInterface
{
   BarInterface *pBar;
}

class Bar : public BarInterface
{
   FooInterface *pFoo;
}

Это нарушает цикл зависимостей (если сами интерфейсы не зависят друг от друга, и если это так, то они, вероятно, должны быть объявлены в одном файле)

2
ответ дан 3 December 2019 в 15:51
поделиться

В вашем примере foo зависит от bar (так как он содержит реальный объект bar), но bar не зависит от foo (так как он содержит только foo *). Теперь bar зависит от имени типа foo, поэтому bar.h нуждается в прямом объявлении имени: class foo;. foo зависит от bar, поэтому foo.h должен содержать #включить "bar.h"

В C++ нельзя иметь классы, которые напрямую зависят друг от друга; это просто не работает. Нужно развязывать классы так, чтобы один зависел только от другого, как в вашем примере. Единственное, что создает прямую зависимость - это использование класса в качестве базового класса или поля; любое другое использование просто создает косвенную зависимость, что обычно не является проблемой.

1
ответ дан 3 December 2019 в 15:51
поделиться

Насколько я знаю, единственный реальный способ сделать это - это использовать указатели, так как они не требуют определения класса до тех пор, пока единица трансляции (.cpp) не будет определена правильно.

0
ответ дан 3 December 2019 в 15:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: