避免循环依赖 - 需要相互遏制

sja*_*rni 1 c++ mutual-recursion containment

在我的GUI系统中,主要构建块是Container类,可以绘制(=可绘制).然而,Container它本身就是一种" 一种表 " - 它包含细胞.

Cellclass用于布局.容器具有的单元格数由行数和列数定义.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,
Run Code Online (Sandbox Code Playgroud)

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;
// ...
}
Run Code Online (Sandbox Code Playgroud)

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;
// ...
}
Run Code Online (Sandbox Code Playgroud)

有一个很好的方法如何使用智能指针解决这种情况(可能通过重新设计整个问题解决方案),或者我必须在这里使用原始指针?

Com*_*sMS 5

std::unique_ptr 适用于前向声明的类型,但它需要知道调用删除器的完整类型.

如果您的类使用编译器生成的析构函数,这将使您感到困惑.您可以通过在源文件中为该类定义一个(可能为空的)自定义析构函数来解决该问题,其中该文件的类型的完整类型定义unique_ptr是可见的.

有关血淋淋的细节,请参阅此答案.