【问题标题】:How to solve a specific circular dependency?如何解决特定的循环依赖?
【发布时间】:2014-11-13 03:44:53
【问题描述】:

所以我的问题不在于代码,而在于实现它的方式。 我正在开发一个 GUI,我希望我的按钮知道父母是谁。当然,窗口知道它有哪些按钮。

这会产生循环依赖,因为两者都需要能够访问其他方法和属性,至少这是我更喜欢的。

我找到了一个可行的解决方案,但我对此不太满意:

我创建了按钮写入的第三个对象,它希望窗口做什么。窗口会检查第三个对象是否有命令。

我想问你,如果你知道更好的方法,因为我找不到任何其他方法,这对我有用。

谢谢!

【问题讨论】:

  • 为什么要避免循环依赖?
  • @GingerPlusPlus 因为循环依赖是糟糕设计的标志。
  • @GingerPlusPlus 因为您无法编译具有循环依赖关系的代码,并且如果您首先拥有它们,则您的代码架构不正确。
  • 由于这是我为熟悉 c++ 而编写的程序,因此我选择了cyber的答案:因为我的编译器不允许我编译它。
  • 尝试将对象引用为指针,我知道循环依赖使用指针的工作方式和不使用指针之间存在差异。但是我这里没有参考=/

标签: c++ class include dependencies


【解决方案1】:

我建议创建一个窗口界面。在按钮的构造函数中提供指向窗口界面的反向指针。拥有按钮的窗口依赖于按钮,而按钮依赖于窗口界面。没有循环依赖。

struct IWindow {
};

struct Button {
 IWindow* window_;
 Button(IWindow* window) : window_(window){}
};

struct WindowWithButton : IWindow {
  Button button_;
  WindowWithButton() : button_(this) {}
};

然后给IWindow添加由WindowWithButton实现的虚方法,这样Button就可以从WindowWithButton得到它需要的信息。

【讨论】:

  • 非常感谢!这比我想出的要好得多。
【解决方案2】:

这是一个标准模式:

struct Window; // Forward-declare the parent
struct Button {
    void pingParent(); // Only declare members which need
        // more than superficial knowledge of Window
    Window* parent; // Ok, we know there is a Window, somewhere
};
struct Window {
    unique_ptr<Button> child;
    // Other functions using the button
    void pingpong() {child->pingParent();}
    void ping(){}
};
/*optional inline*/ void Button::pingParent() {
    parent->ping();
}

【讨论】:

  • 也谢谢你。您的解决方案也可以。但是当我使用包含时,我不需要在 Window.h/Window.cpp 中定义实际的 pingParent() 吗?这不是让代码很混乱吗?
  • 您在标题中定义它,因此每个调用它的 TU 都有定义。如果你不使用inline,它必须在一个实现文件中,而不是在头文件中。除非需要,否则我会避免使用接口(带有用于覆盖的虚函数),因为使用它们会带来性能和空间损失。
猜你喜欢
  • 1970-01-01
  • 2012-03-15
  • 2016-09-21
  • 2020-11-12
相关资源
最近更新 更多