2012-12-18 36 views
0

我不知道如何命名这个问题,所以我会尽力解释。根据两种对象类型选择正确的策略

我希望能够根据两个不同对象的类型切换策略。为了使这个工作,我想用一个枚举类型标记对象,并有这些策略的“注册表”(阵列)。理想情况下,正确的策略可以通过一些简单的操作来访问,如两种类型之间的按位运算符。

这种伪可能会让我尝试解释更容易理解:

enum Type { A, B, C } 

struct Object { 
    Type type; 
} 

class ActionRunner { 
    vector<Strategy> strategies; 

    void registerStrategy(type1, type2, strategy) { 
    strategies[type1 operator type2] = strategy; 
    } 

    void runStrategyFor(type1, type2) { 
    strategies[type1 operator type2].execute(); 
    } 
} 

这将是很容易使用的地图来解决,但我想使用,因为地图数组或向量看起来像这样的问题矫枉过正,使用数组可能要快得多。

所以问题是我不知道我可以用什么算子来选择正确的策略的'位置'。我一直在考虑一些组合,但似乎所有这些组合在某个时刻都会导致与不同组合的碰撞。

有没有人有任何线索/建议我可以用这个? PS:我知道不成熟的优化是不好的,但我只是想弄明白这个问题是否可以用简单的方法解决。

-------编辑-------------------------------------- ----------

鉴于答案,我一直在给这个问题一些额外的想法,我已经得出结论,我打算用这个问题是不可能的方式我喜欢它。我将尝试使用这个问题重新陈述我现在要解决的问题。

我想要一个类结构,其中有一些特定类型的对象'BaseClass'和一个'处理器'对象,它接受两个从'BaseClass'派生的对象并为这些对象运行正确的策略。事情是这样的:

class Processor { 
    void run (DerivedA a, DerivedB b); 
} 

class BaseClass {} 
class DerivedA: public BaseClass {} 
class DerivedB: public BaseClass {} 

BaseClass a = new DerivedA; 
BaseClass b = new DerivedB; 

processor.run(a, b) 

据我了解,这不会好像什么作为参数,以“跑”过去,我所期待的工作是引用,这是我宁愿做。有没有办法做到这一点没有方式太复杂的代码? (tripple dispatch !?)

我记得像双重调度与一个奴隶(处理器)对象,我认为会工作,但这似乎非常复杂,可能是一个维护和扩展的痛苦。

谢谢!

+0

你可以尝试短语你正在试图做的更好呢?也许还要通过示例来展示它。 – Dukeling

回答

0

你问题的第二句摇铃对我来说:

我希望能够根据种类两个不同的对象的切换策略。

这听起来像是你想要执行double dispatch。请参阅Double dispatch/multimethods in C++的问题(特别是问题的答案;-)),以了解如何在C++中实现此功能。

+0

我认为在这个问题中,*类型*不是标准的C++类型。这是一个描述对象的**值**。这是它从发布的代码中看起来的样子 – SomeWittyUsername

+0

@icepack:也许这也是一个提示:如果只有三个C++类(in),而不是具有'type'字段的对象取三个值之一这种情况下,问题I中的双重调度实施变得相关)。 –

+0

我实际上首先想到了语言类型,但是我开始考虑使用值来定义类型,以探索使用简单运算符访问“策略注册表”的可能性。这可能不是最好的设计选择,但我只是在这个阶段探索选项。 – uorbe001

0

这是使用map而不是数组的典型示例。数组实际上是一个私人大小写map,其中的键定义为一个整数。在你的情况下,关键是一个元组,所以一个简单的数组不会做,并且最终会发生冲突(即使你对于特定输入你很幸运,你的代码将非常不健壮)。

你可以有一个中间的解决方案,简单arraymap之间:2D array,与2种作为指数行和列..

+0

在给了我一些额外的想法后,我得出了和你一样的结论没有。地图唯一的问题是它可能比数组慢。二维数组是我考虑过的一个很好的选择,但这意味着在大多数情况下(至少我考虑的方式),必须分配更多的内存。 我在这里考虑的可能不是最好的设计选项。 – uorbe001

+0

@ uorbe001有很多方法可以最大限度地减少内存使用量。例如,您可以为每个组合使用'if..else'语句来实现自己的操作符,这些语句将返回1D数组中的索引 - 它可以工作,但很丑,并且会导致性能损失。最重要的是,不管你做什么,你会在空间或时间(或两者兼而有之)支付 – SomeWittyUsername

+0

是的,我试图从客户端代码中找到一种“插入”策略的方式,但它看起来并不像有效地做到这一点(从空间和时间的角度来看)。我认为我的问题的最佳选择可能是内置一些“核心”策略,并且可能允许客户端代码注册新策略,尽管时间/空间成本很高。理想情况下,我希望所有策略都能“插入”以提高二进制兼容性,但其缺点让我认为尝试这种做法可能是一个糟糕的主意。 – uorbe001