繁体   English   中英

C ++避免向下转发

[英]C++ Avoiding downcasting

我需要解析源代码。 我已经确定了3种不同类型的标记:符号(运算符,关键字),litterals(整数,字符串等)和标识符。

我已经有了以下设计,其中有一个跟踪子类类型的基类,因此可以使用基类指针对其进行下载:

class Token
{
    type_e type; // E_SYMBOL, E_LITTERAL, E_TOKEN
};

class Symbol : public Token
{
    const symbol_e symbol;
};

class Litteral : public Token
{
    const Value value;
};

class Identifier : public Token
{
    const std::string name;
};

我需要将这些类存储在一个令牌数组中,这就是为什么我需要它们有一个共同的基类。 然后我像这样使用它们:

if( cur->type == E_SYMBOL && static_cast< const Symbol * >( cur )->symbol == E_LPARENT )
{
    // ...
}

我可以创建虚函数isSymbol,isLitteral,isIdentifer,每个子类都会覆盖,但我仍然需要将基类指针向下转换为子类指针, 以便我可以访问子类的特定数据。

人们说向下转换意味着界面可能存在缺陷,并且它使语法非常沉重,所以我想找到另一种方式,但我不能。 有些人建议访问者模式,但我担心这会无用地复杂化代码,我甚至不明白我如何使用访问者模式来解决这个问题。

有人可以帮忙吗? 谢谢 :)

你有三个选择。 每种解决方案都有其优点和缺点。

  • 将逻辑放入令牌类中,因此调用代码不需要知道它正在处理哪种令牌。

    这将是“最纯粹的面向对象”解决方案。 缺点是逻辑倾向于在基类和子类之间传播,这使得它更难以遵循。 它也可能导致类增长相当大。 但是编译器/解释器通常没有那么多的操作会成为问题。

  • 使用访客模式

    这是一个接口TokenVisitor其中visit方法为令牌子类型重载,并在Tokenaccept(TokenVisitor&)方法,每个子类将覆盖该方法以调用适当的visit重载。

    您现在需要知道接口中的完整令牌类型集,但它允许保持类合理地小,并按行动分组逻辑通常更容易遵循。

  • 使用有区别的联合,例如Boost.Variant

    这根本不是面向对象的。 它将导致在整个地方切换类型,并可能看起来很难看。 但由于逻辑总是在一起,因此通常更容易理解,特别是对于那些不理解代码背后的想法的人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM