Как создать два класса на С++, которые используют друг друга в качестве данных?
Я хочу создать два класса, каждый из которых содержит объект другого типа класса. Как я могу это сделать? Если я не могу этого сделать, есть ли работа, например, если у каждого класса есть указатель на другой тип класса? Спасибо!
Вот что у меня есть:
Файл: 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
Ответы
Ответ 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