我有一个层次结构:
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/