【问题标题】:c++ automatic deduction of derived classesc++派生类自动推演
【发布时间】:2015-04-23 18:03:21
【问题描述】:

假设我有一个这样的基类:

class BaseNode
{
    BaseNode* nodeA;
    BaseNode* nodeB;
};

派生类如下:

class DecisionNode : public BaseNode
{
    //lots of variables and functions about decision making
};

class ActionNode : public BaseNode
{
    //lots of variables and functions about performing actions
};

还有一种逻辑类:

class Logic
{
    std::vector<BaseNode*> nodes;//contains DecisionNodes and ActionNodes...

    void handleNodeAutomatically(BaseNode* node)
    {
        //some funky deduction code....
        //send the node to the relevant function below
    }

    void handleDecisionNode(DecisionNode* node)
    {
        //perform decision-specific code here....
    }

    void handleActionNode(ActionNode* node)
    {
        //perform action-specific code here....
    }
};

您对我应该如何实现“handleNodeAutomatically”功能有何建议?或者我对这应该如何工作的整个想法完全是垃圾(如果是的话,请告诉我!)

我知道我可以做以下事情:

if(dynamic_cast<ActionNode*>someNode != NULL) //it turns out it's an action

但这对我来说似乎有点令人费解。而且我相信 dynamic_cast 也有一些相关的开销。

我也可以只有一个大的 actionAndDecisionNode 类 all 两个类的属性和一个布尔“isDecisionNode”值,然后只测试那个,或者一个“nodeType”枚举,但是这些方法感觉有点乱。

所以,如果您喜欢,请尝试填写“handleNodeAutomatically”函数中的空白。或者,或者,告诉我这个计划注定要失败,并告诉我一个更好的方法。

谢谢!

【问题讨论】:

  • 你正在尝试做的事情看起来像一个 CRTP 模式又名静态多态性。
  • 听起来像是一个有用的新概念......(谷歌搜索'我会去......)
  • wikipedia 不过,它不会让你的代码不那么混乱。
  • 下面的答案通常是比 dynamic_cast 更好的选择,但两者都是可行且易于理解的解决方案。您似乎担心事情会变慢,但除非您的程序所做的只是整天调用空函数,否则这两种解决方案都不会出现在配置文件中。
  • 也可以查看所谓的访问者模式。如果仅在派生类中需要某些东西但在基类接口中需要某些东西,它可以避免使用大量空虚函数使类层次结构混乱。

标签: c++ inheritance polymorphism derived-class


【解决方案1】:

您可能在所有三个类中都有一个方法,并从 Logic 类中调用它:

class BaseNode {
    // ...
    virtual void foo();
};

class ActionNode : public BaseNode {
    // ...
    void foo(); // implements the Action version of foo()
};

class DecisionNode : public BaseNode {
    // ...
    void foo(); // implements the Decision version of foo()
};

然后:

class Logic {
    void handleNodeAutomatically(BaseNode* node)
    {
        node->foo();
    }
};

注意: 有关一些技术细节,请参阅下面的 cmets(@BasileStarynkevitch 和 @ChristianHackl)。

【讨论】:

  • 我相信foo应该经常是virtual里面BaseNode
  • 是的...当你这样说的时候看起来很不错...出于某种原因我不记得了,但我想我不想这样做...
  • @Argh 为什么不呢?这是实现您所拥有的东西的一种干净且合乎逻辑的愉快方式。这就是多态的力量。
  • @Argh:为什么不呢?这似乎是正确的方法(减去一些技术细节缺失,例如虚拟析构函数的必要性)。
  • @jadhachem:您应该在此示例中添加一个虚拟析构函数,并考虑将 virtual (pre-C++11) 或 override (C++11) 添加到重写的函数中以记录它们覆盖虚函数的事实。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
相关资源
最近更新 更多