Подтвердить что ты не робот

Как создать два класса на С++, которые используют друг друга в качестве данных?

Я хочу создать два класса, каждый из которых содержит объект другого типа класса. Как я могу это сделать? Если я не могу этого сделать, есть ли работа, например, если у каждого класса есть указатель на другой тип класса? Спасибо!

Вот что у меня есть:

Файл: bar.h

#ifndef BAR_H
#define BAR_H
#include "foo.h"
class bar {
public:
  foo getFoo();
protected:
  foo f;
};
#endif

Файл: foo.h

#ifndef FOO_H
#define FOO_H
#include "bar.h"
class foo {
public:
  bar getBar();
protected:
  bar b;
};
#endif

Файл: main.cpp

#include "foo.h"
#include "bar.h"

int
main (int argc, char **argv)
{
  foo myFoo;
  bar myBar;
}

$g++ main.cpp

In file included from foo.h:3,
                 from main.cpp:1:
bar.h:6: error: ‘foo’ does not name a type
bar.h:8: error: ‘foo’ does not name a type
4b9b3361

Ответ 1

У вас не может быть двух классов, непосредственно содержащих объекты другого типа, так как в противном случае вам понадобится бесконечное пространство для объекта (поскольку foo имеет панель с foo, которая имеет панель, которая и т.д.)

Вы действительно можете сделать это, если два класса сохраняют указатели друг на друга. Для этого вам нужно будет использовать форвардные объявления, чтобы два класса знали друг о друге:

#ifndef BAR_H
#define BAR_H

class foo; // Say foo exists without defining it.

class bar {
public:
  foo* getFoo();
protected:
  foo* f;
};
#endif 

и

#ifndef FOO_H
#define FOO_H

class bar; // Say bar exists without defining it.

class foo {
public:
  bar* getBar();
protected:
  bar* f;
};
#endif 

Обратите внимание, что два заголовка не включают друг друга. Вместо этого они просто знают о существовании другого класса через передовые декларации. Затем в файлах .cpp для этих двух классов вы можете #include использовать другой заголовок, чтобы получить полную информацию о классе. Эти передовые декларации позволяют вам разорвать опорный цикл "foo need bar нуждается в баре потребностей foo".

Ответ 2

Это не имеет смысла. Если A содержит B, а B содержит A, это будет бесконечный размер. Представьте себе, что у вас есть две коробки, и пытайтесь поместить друг в друга. Не работает, правильно?

Указатели работают, хотя:

#ifndef FOO_H
#define FOO_H

// Forward declaration so the compiler knows what bar is
class bar;

class foo {
public:
  bar *getBar();
protected:
  bar *b;
};
#endif