我有一个C++基类CAbstrInstruction和大量直接子类:

class CAbstrInstruction { /* ... */ };

class CSleepInstruction: public CAbstrInstruction { /* ... */ };
class CSetInstruction: public CAbstrInstruction { /* ... */ };
class CIfInstruction: public CAbstrInstruction { /* ... */ };
class CWhileInstruction: public CAbstrInstruction { /* ... */ };
// ...

还有一个CScriptWorker,它公开了一个公共(public)方法execute:
class CScriptWorker
{
    public:
        void execute (const CAbstrInstruction *pI);

    private:
        void doSleep (const CSleepInstruction *pI);
        void doSet (const CSetInstruction *pI);
        void doIf (const CIfInstruction *pI);
        void doWhile (const CWhileInstruction *pI);
        // ...
};

当前execute方法的实现如下所示:
void CScriptWorker::execute (const CAbstrInstruction *pI)
{
    const CSleepInstruction *pSleep =
        dynamic_cast<const CSleepInstruction *>(pI);

    if (pSleep != NULL)
    {
        doSleep (*pSleep);
        return;
    }

    const CSetInstruction *pSet =
        dynamic_cast<const CSetInstruction *>(pI);

    if (pSet != NULL)
    {
        doSet (*pSet);
        return;
    }

    const CIfInstruction *pIf =
        dynamic_cast<const CIfInstruction *>(pI);

    if (pIf != NULL)
    {
        doIf (*pIf);
        return;
    }

    const CWhileInstruction *pWhile =
        dynamic_cast<const CWhileInstruction *>(pI);

    if (pWhile != NULL)
    {
        doWhile (*pWhile);
        return;
    }

    /* ... */
}

这非常笨拙,需要O(log(n))来调用正确的私有(private)方法。在那儿
有任何设计模式或语言构造可以简化这一过程吗?

澄清:我可以将专用执行方法do ...移至指令中
类。 execute方法将变成:
    void execute (const CAbstrInstruction *pI) { pI->execute(); }

但是,那不是我想要的。为什么不? 关注点分离:CAbstrInstruction的实例仅是对要执行的操作的描述。它们组成了脚本的抽象语法树。这已经足够了。 CScriptWorker的关注点是实际执行指令中描述的内容。 CScriptWorker知道脚本在其中运行的上下文。CAbstrInstruction不应该知道这一点。

最佳答案

CAbstrInstruction应该定义一个纯虚方法(在您的示例中为execute()),您的子类应该重写并实现。

举个例子:

class CAbstrInstruction
{
     /* ... */
     virtual void execute() const = 0;
}

class CSleepInstruction
{
     /* ... */
     void execute() override const
     {
         /* your code here */
     }
}

/* ... */
void CScriptWorker::execute (const CAbstrInstruction *pI)
{
    pI->execute();
}

10-05 19:38