Избегайте циклических зависимостей — необходимо взаимное сдерживание

В моей системе GUI основным строительным блоком является Container класс, который можно нарисовать (= рисуется). Тем не мение, Container сам по себевид стола‘- он содержит клетки.

Cell класс служит для Оформление печатных изданий. Количество ячеек в контейнере определяется количеством строк и столбцов.Cell объекты не видны.

И вот проблема. Cell объекты не могут быть нарисованы — они содержат Container объекты, которые нарисованы по правилам, определенным в Cell объект (выравнивание, заполнение и т. д.) при вызове cell.draw(),

Я знаю, что это можно легко решить, используя необработанные указатели, чтобы избежать создаваемой здесь циклической зависимости, но я хотел использовать умные указатели, если это возможно. Тем не менее, в соответствии с ошибкой, которую я получаю, это очевидные умные указатели должен знать размер объекта, в отличие от необработанных указателей.

Ошибка Unique_ptr

/usr/include/c++/4.8/bits/unique_ptr.h:65:22: error: invalid application of ‘sizeof’ to incomplete type ‘Container’
static_assert(sizeof(_Tp)>0,

Container.hpp

#include <Cell.hpp> // Causes circular dependency
class Cell; // Causes error: invalid application of ‘sizeof’

class Container
{
// ...
private:
std::vector<std::unique_ptr<Cell>> cells;
// ...
}

Cell.hpp

#include <Container.hpp> //Causes circular dependency
class Container; // Causes error: invalid application of ‘sizeof’
class Cell
{
// ...
private:
std::vector<std::unique_prt<Container>> subcontainers;
// ...
}

Есть хороший способ, как решить ситуацию с помощью умных указателей (может быть, путем перепроектирования всего решения проблемы), или я должен использовать здесь необработанные указатели?

1

Решение

std::unique_ptr работает с заранее объявленными типами, но ему нужно знать полный тип для вызова средства удаления.

Это укусит вас, если ваш класс использует сгенерированный компилятором деструктор. Вы можете избавиться от проблемы, определив (возможно пустой) пользовательский деструктор для класса вне строки в исходном файле, где полное определение типа для типа содержится в unique_ptr виден

Ссылаться на этот ответ для кровавых деталей.

5

Другие решения

Ответ:
Я думаю, у вас должен быть один контейнер, содержащий контейнеры: D у каждого контейнера есть метод getCells ().

0