In my GUI system, the main building block is Container
class, which can be drawn (= is drawable). However, Container
itself is a 'kind of a table' - it contains cells.
Cell
class serves for layouting. The number of cells a container has is defined by number of rows and columns.Cell
objects are not visible.
And here's the problem. Cell
objects cannot be drawn - they contain Container
objects, which are drawn by the rules defined in the Cell
object (alignment, padding, etc..) when calling cell.draw()
.
I know this can be easily resolved by using raw pointers to avoid the circular dependency created here, but I wanted to use smart pointers, if possible. However, according to error I'm getting, it's obvious smart pointers have to know the size of the object, unlike raw pointers.
Unique_ptr error
/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;
// ...
}
Is there a nice way how to solve the situation using smart pointers (maybe by redesigning the whole problem solution), or do I have to use raw pointers here?
std::unique_ptr
works on forward declared types, but it needs to know the full type for invoking the deleter.
This will bite you if your class uses a compiler-generated destructor. You can get rid of the problem by defining a (possibly empty) custom destructor for the class out-of-line in a source file where the full type definition for the type held by the unique_ptr
is visible.
Refer to this answer for the gory details.