С++ "Недопустимый тип недопустимый" ошибка доступа к справочной информации класса (круговая зависимость с форвардной декларацией)

Недавно в моем коде были некоторые проблемы, связанные с тем, что я теперь знаю как круговая зависимость. Короче говоря, есть два класса, Player и Ball, которые оба должны использовать информацию от другого. Оба в какой-то момент в коде будут переданы ссылки на другой (из другого класса, который будет включать оба .h файлов).

Прочитав его, я удалил файлы # include.h из каждого и приступил к предварительному объявлению. Это решило проблему возможности объявлять классы друг в друге, но теперь я остаюсь с "неполной ошибкой типа" при попытке получить доступ к переданной ссылке на объект. Кажется, есть несколько похожих примеров, хотя они часто смешиваются с более сложным кодом и его трудно сузить до основ.

Я переписал код в его простейшей форме (по сути, скелет).

Ball.h:

class Player;

class Ball {
public:
    Player& PlayerB;
    float ballPosX = 800;
private:

};

Player.h:

class Ball;

class Player {
public:
    void doSomething(Ball& ball);
private:
};

Player.cpp:

#include "Player.h"

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}

Любая помощь, понимая, почему это так, будет принята с благодарностью :)

Ответы

Ответ 1

Если вы поместите свои определения в этом порядке, тогда код будет скомпилирован

class Ball;

class Player {
public:
    void doSomething(Ball& ball);
private:
};

class Ball {
public:
    Player& PlayerB;
    float ballPosX = 800;
private:

};

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}

int main()
{
}

Определение функции doSomething требует полного определения класса Ball, поскольку оно обращается к его члену данных.

В вашем примере кода модуля Player.cpp не имеет доступа к определению класса Ball, поэтому компилятор выдает ошибку.

Ответ 2

Player.cpp требуется определение класса Ball. Поэтому просто добавьте #include "Ball.h"

Player.cpp:

#include "Player.h"
#include "Ball.h"

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}

Ответ 3

Вот что я имел и что вызвало мою "ошибку неполного типа":

#include "X.h" // another already declared class
class Big {...} // full declaration of class A

class Small : Big {
    Small() {}
    Small(X); // line 6
}
//.... all other stuff

Что я сделал в файле "Big.cpp", где я объявил конструктор A2 с X в качестве параметра...

Big.cpp

Small::Big(X my_x) { // line 9 <--- LOOK at this !
}

Я написал "Small:: Big" вместо "Small:: Small" , какая глупая ошибка.. Я получил ошибку "неполный тип теперь разрешен" для класса X все время (в строках 6 и 9), что вызвало полную путаницу.

В любом случае, здесь может произойти ошибка, и главная причина в том, что я устал, когда писал, и мне нужно было 2 часа изучения и перезаписи кода, чтобы раскрыть его.