C ++:推荐用于类功能子集的设计模式?

时间:2013-12-11 06:05:34

标签: c++ design-patterns member-function-pointers

我正在寻求一种适合我需求的设计模式的建议:

在我的C ++项目中,一个特定的纯虚拟类将代表某个概念的所有相关功能的超集,并且从该纯虚拟类派生的具体类将分别是该超集的一些不同的有限子集。在运行时只存在这些具体类中的任何一个实例。

如果我使用C编程,我可能会选择将其实现为函数指针的结构,对于任何缺少的功能都使用NULL。但这对C ++来说并不十分令人满意。

关于我能想到的唯一想法是一个类,每个成员函数都是'protected',还有一组匹配的'public'成员函数指针。构造函数将负责将MFP初始化为NULL或相应成员函数的地址,具体取决于类提供的功能。

但这实际上只是C ++ - 比我上面提到的C-struct-of-function指针要少得多。而且,也许它足够好了。但我想知道是否有人可以为这种情况建议一个更令人满意,更有洞察力的设计模式。

我对任何普遍接受的做法持开放态度。 STL很好。

更新:MFP方法不太令人满意的原因是我必须为那些不适用的方法实现无操作的存根 - 因为纯虚基类 - 即使我将各自的MFP设置为NULL。经过进一步反思,此更新完全是假的。 (在没有使用NULL的情况下,它们不会是无用的存根,它们将是有用的功能。我认为我很累。)

更新2 :类比:我的项目支持可以换出的硬件模块。它们基本上都是相同的功能类别,但功能和功能各不相同。在启动时,我必须检测实际连接的硬件模块,并实例化相应的类。但我不希望使用该类的代码具有每个类的特殊知识;我希望课程宣传它提供的功能。 (有时,两个硬件模块将识别为相同的类型ID,但在功能探测器上,一个将指示另一个不具备的功能。)

2 个答案:

答案 0 :(得分:3)

您的设计要求违反了非常重要的OOP principle。 如果一个类或一个函数依赖于那个“超集”接口,那么编译器将永远无法强制执行类型安全 - 你基本上是在与它作斗争,为了什么?

我建议您segregate您的接口,并创建一个实现所有接口的具体(可能是纯虚拟)类。这种设计模式有一个名称 - 它叫做facade

更新我现在阅读您的更新,我相信您需要一个用于推广对象的工具。 有两种促销活动:

  • 实施促销:
    这是您基本上替换对象的实现的地方。这可以通过state模式完成,也可以通过将对象放置到具有不同VTABLE的模式来完成。
  • 功能促销:
    这是添加功能的地方,就像在更多功能中一样。您可以通过从硬件模块的名称到其变体指针的映射来完成此操作。将对象提升为其他类时,只需替换指针变体即可。例如,如果您的第一个映射来自“COM1” - > GenericSerial*,然后你现在设置“COM1” - > SpecializedSerial*。您可以使用变体库,例如boost's

答案 1 :(得分:0)

为什么不这样做:

interface All {
    void f1();
    void f2();
    void f3();
}
abstract class AllABC implements All {
    public void f1() {
        throw new RuntimeException("not implemented");
    }
    public void f2() {
        throw new RuntimeException("not implemented");
    }
    public void f3() {
        throw new RuntimeException("not implemented");
    }
}
class F12 extends AllABC {
    public void f1() {
        System.out.println("f1");
    }
    public void f2() {
        System.out.println("f2");
    }
}
class F13 extends AllABC {
    public void f1() {
        System.out.println("f1");
    }
    public void f3() {
        System.out.println("f3");
    }
}
public class So20511733 {
    public static void main(String[] arguments) {
        All f12=new F12();
        f12.f1();
        f12.f2();
        All f13=new F13();
        f13.f1();
        f13.f3();
    }
}