我有一个层次结构:

class ICommand
{
    public:
        virtual void start() = 0;
};

class IExtendedCommand : public ICommand
{
    public:
        virtual void doSomethingElse() = 0;
};

class ConcreteCommand : public ICommand
{
    public:
        virtual void start() {};
}
class ExtendedConcreteCommand : public ConcreteCommand, public IExtendedCommand
{
    public:
        virtual void doSomethingElse() {};
}

ICommand 和 IExtendedCommand 对象由工厂创建。

出于某种原因,当编译器说所有 ICommand 的方法在 ExtendedConcreteCommand 中都是纯方法时......

任何想法为什么以及如何解决这个问题?

PS: 是的,我正在将我的 Android 应用程序移植到 C++/Qt(我已经 3 年没有使用了)。
无论如何,我想听听你将如何应对。

编辑:

我正在移植的是一个用于 MPC 和 VLC 的远程控制应用程序。
这个想法是创建可以通过工厂发送给玩家的命令。
工厂返回一个指向实现 ICommand 的对象的指针。因此,通过切换工厂实现可以创建不同的命令。 ICommand 声明了所有主要的方法和信号。 IExtendedCommand 为玩家添加了一些通用信息。所以我想做的是通过工厂实例化 IExtendedCommand,设置一些属性,然后用 start() 方法启动它。另外我想重用 ConcreteCommand 的功能。这导致了我描述的问题。

最佳答案

你没有钻石。你有这个:

   +----------------------------------- missing start() !
   V
pv start()     pv doSomethingElse()     concrete doSomethingElse()

ICommand  ---> IExtendedCommand   ---\
                                      > ExtendedConcreteCommand
ICommand  ---> ConcreteCommand    ---/

pv start()     concrete start()

这意味着您有 两个 类型的 ICommand 基类,并且您需要覆盖它们的纯方法。但是只有 ConcreteCommand 覆盖了 start 的“底部”版本,而另一个保持未覆盖。

如果你想要一个真正的钻石,你需要使用虚拟继承使 ICommand 基类成为虚拟的: class IExtendedCommand : virtual public ICommand ,对于 ConcreteCommand 也是如此。或者,您可以在 start 中为 ExtendedConcreteCommand 提供另一个覆盖程序。

关于C++菱形接口(interface)继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13088519/

10-12 15:05