【问题标题】:C++ circular dependency and inheritanceC++循环依赖和继承
【发布时间】:2013-09-27 21:05:11
【问题描述】:

(我阅读了其他依赖/循环继承问题,但找不到此特定案例的答案)

我有一个父类 InputDevice,它将产生两个子类之一。 InputDevice1 是我们希望连接到每台计算机的东西,而 InputDevice2 是可能连接到计算机的东西,我们必须检查它是否是。 InputDevice1 和 InputDevice2 将具有相同的访问器,但内部逻辑非常不同。

我似乎无法解决依赖性问题 - 解决方案可能是我还没有想出的解决方案,或者我的设计可能很糟糕。

我的 InputDevice.h 看起来像

class InputDevice{
private:
    InputDevice* inputDevice;

public:
    static InputDevice* GetDevice() {
        //we expect only one type of device to be 
        //connected to the computer at a time.

        if (inputDevice == nullptr) {
            if (InputDevice2::IsConnected)
                inputDevice = new InputDevice2();
            else
                inputDevice = new InputDevice1();    
        }

        return inputDevice;
    }

    ...standard accessors and functions...
};

而 InputDevice1.h 是:

class InputDevice1 : public InputDevice{
public:
    ...declarations of any functions InputDevice1 will overload...
}

而 InputDevice2.h 是:

class InputDevice2 : public InputDevice{
public:
    static bool IsConnected();

    ...declarations of any functions InputDevice2 will overload...
}

我不确定将#include 语句放在哪些文件中... InputDevice.h 是引用 InputDevice2.h 还是相反?我也尝试过前向声明类,但这似乎也不起作用。

【问题讨论】:

  • 你在混合概念。 InputDevice 定义了一个接口,它不应该知道哪些类型可能从它继承。不同的类可以处理可用/使用的输入设备的实际实例。您可以通过仔细使用前向声明并拆分类型和实现的定义来使其编译,但您可能需要考虑重新设计

标签: c++ inheritance circular-dependency


【解决方案1】:

我认为最简单的答案是将您的抽象类 - InputDevice 及其所有访问器和函数 - 与您正在显示的工厂功能分开,即在另一个名为 InputDeviceFactory 的文件中创建另一个类,然后放入GetDevice 在里面。

那么这两个具体的实例会包含InputDevice.h,工厂会包含InputDevice1.h和InputDevice2.h并且只是前向声明InputDevice类,InputDevice.h会包含InputDeviceFactory.h。

实际上,InputDevice.h 不应该包含 InputDeviceFactory。需要工厂的实现应该在 .cpp 中,而不是 .h 中。这也可以让您在工厂中包含 InputDevice.h,而无需进行前向声明。这给我带来了一些不请自来的一般建议: 尽量避免将实现(例如GetDevice)放在.h 文件中。如果只将声明放在 .h 文件中,则可以在任何地方包含 .h 文件,除非存在真正的循环依赖,否则无需担心前向引用。

【讨论】:

  • 这是我采用的解决方案。我没有创建另一个InputDeviceFactory 类,我只是有一个可以从任何地方调用的函数GetInputDevice()
【解决方案2】:

这不是循环依赖问题。您只需要在InputDevice.hInputDevice1.h 中引用Parent 类。

#include "InputDevice.h" 放在两个子类中。父类不需要知道它的子类。

【讨论】:

    【解决方案3】:

    您不能在InputDevice定义 InputDevice::GetDevice,因为尚未看到Device2(对于Device2::IsConnected)的定义。所以去掉InputDevice::GetDevice的实现 并将其放入源文件中,在 #includeing 所有三个标头之后。

    【讨论】:

      猜你喜欢
      • 2022-01-16
      • 1970-01-01
      • 2018-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多