删除树节点的派生类中的dynamic_cast

时间:2015-11-20 16:13:21

标签: c++ inheritance dynamic-cast

我有一个类,它是一个树的节点,称为Node。我需要创建一个DerivedNode类类型,它具有一些额外的功能。问题是Node有一个Node *向量作为成员变量,所以当DerivedNode继承自Node时,它继承了这个向量。我已经创建了一个显示问题的基本示例:

#include <iostream>
#include <vector>

class Node {
public:
    Node(int value_) : value(value_) {}
    int foo() { return value; }
    virtual void add(Node* new_node) {
        children.push_back(new_node);
    }
protected:
    std::vector<Node*> children;
    int value;
};

class DerivedNode : public Node {
public:
    DerivedNode(int value_) : Node(value_) {}
    int bar() { return value*2; }
    // Ensures we only add children of type DynamicNode*
    virtual void add(DerivedNode* new_node) {
        children.push_back(new_node);
    }
    void print() {
        for (size_t i = 0; i < children.size(); ++i) {
            std::cout << dynamic_cast<DerivedNode*>(children[i])->bar() << std::endl;
        }
    }
};


int main() {
    DerivedNode* child_a = new DerivedNode(5);
    DerivedNode* child_b = new DerivedNode(6);
    DerivedNode parent(1);
    parent.add(child_a);
    parent.add(child_b);
    parent.print();
    delete child_a;
    delete child_b;
}

我的问题是,如果没有dynamic_cast,我怎么能这样做?我的实际代码要复杂得多,这意味着到处都有动态转换。

2 个答案:

答案 0 :(得分:0)

首先在派生类中添加函数是完全没用的,它不会覆盖基类的add函数,它会重载它。通过这种方式,您仍然可以将Node *添加到派生类中。为防止这种情况,您应该将add(Node *)覆盖为私有。

如果您不喜欢动态强制转换,则可以使用静态强制转换 要么 您可能在基类中有虚拟栏,它不执行任何操作 要么 你可以转换向量本身(整个事物)并分配给std :: vector DerivedNode *的引用或指针

答案 1 :(得分:0)

你无法双管齐下。你要么在你的classess的设计中反映出IS-A原则,要么你没有。如果DerivedNode是Node,那么Node s的向量应该与DerivedNode s的向量无法区分 - 并且不需要强制转换。如果无法实现,那就根本无法使用基指针向量。

对我来说,生产代码中的任何dynamic_cast对于任何审核都是一个难点,因为它明显违反了基本的设计原则。