Проблемы круговой зависимости с унаследованными классами - PullRequest
0 голосов
/ 20 апреля 2020
//grid.h
class Grid {
    ...
    std::vector<std::vector<Tile>> theBoard;
    ..
}
//tile.h
class Tile {
    ...
    Piece *piece;
    ...
}
//piece.h
class Piece {
    ...
    Grid *theBoard;
    ...
}
//queen.h
class Queen : public Piece {
    ...
}

Мы сталкиваемся с проблемами зависимости, когда пытаемся скомпилировать это. Как мы пишем заголовки включения / форвардные объявления для поддержки этого?

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

В Piece.h вы можете форвард объявить Grid-класс. Прямое объявление означает, что вы сообщаете компьютеру, что определенный тип существует, но он еще ничего не знает о его размере или членах. Вы не можете пересылать объявление в Queen.h, поскольку вам не разрешено наследовать от заранее объявленного класса. Кроме того, вам не разрешено хранить объявленный класс в качестве члена, вы можете хранить только указатель или ссылку на них.

//piece.h
// forward declaration of Grid
class Grid;

class Piece {
    ...
    Grid *theBoard;
    ...
}

Обратите внимание, что в файле реализации piece.h необходимо включить grid.h, чтобы компилятор мог знать, какие методы могут быть вызваны на Grid, но, поскольку этот #include находится в файле реализации, вы не получите циклическую зависимость.

1 голос
/ 20 апреля 2020

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

Другим решением является предварительное объявление класса. Вы могли бы сделать это, написав:

class a;

И это просто говорит компилятору: «Эй, существует, это будет позже». Это может очень быстро запутаться, поэтому, вероятно, лучше попытаться переосмыслить вашу структуру, чтобы ваши классы были более самодостаточными и не зависели друг от друга.

...