Форвардная декларация с вектором типа класса - недопустимый указатель на неполный тип класса
У меня есть два класса: foo и bar. foo включает в себя строку bar и содержит std::vector указателей для отображения объектов. в какой-то момент во время выполнения бар должен получить доступ к этому вектору указателей к другим объектам бара. Поэтому foo содержит метод с именем getBarObjects(), который возвращает массив указателей.
Поэтому я пересылаю декларацию foo в баре. Мне также нужно переслать декларацию метода, который я использую - foo:: getBarObjects(). Поскольку это возвращает массив указателей в бар, я попадаю в порочный круг.
Я не могу перенаправить строку включения, а затем просто переслать include getBarObjects(), поскольку это приводит к тому, что недопустимое имя типа недопустимо.
foo.h:
#include "bar.h"
#include <vector>
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
}
bar.h:
class foo;
std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp:
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
}
Если я просто включу другой способ, у меня будет такая же проблема в foo lateron. Любые предложения?
Ответы
Ответ 1
Вы не можете перенаправлять объявления.
Вместо этого bar.cpp
должен #include
как foo.h
, так и bar.h
. Проблема решена.
В общем случае, если вы используете последовательность:
- Вперед объявить все типы классов
- Определить все типы классов
- Тела участников класса
все будет хорошо.
Ответ 2
Вам не нужно включать foo.h или bar.h друг в друга, если вы не получаете доступ к внутренним компонентам любого класса из другого заголовочного файла. Объявите классы по мере необходимости в файлах заголовков, затем включите оба файла заголовка из исходного файла.
foo.h
#include <vector>
class bar;
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
};
bar.h
class foo;
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp
#include "foo.h"
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects();
}
Ответ 3
Вы забыли переслать объявление в foo.h. Вы также возвращаете значение vector
из getBarObjects
, которое, возможно, не то, что вы хотите, и прямое объявление функции-члена бесполезно.
Также: используйте защитные элементы заголовка. Предпочитайте соответствующий умный указатель для вашей ситуации (std::shared_ptr
, unique_ptr
) над необработанными указателями. Следите за const
ness.