Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当涉及多态类型时,如何避免过度使用动态转换/我是否正确地将它们用于AST?_C++_Casting_Compiler Construction_Polymorphism_Abstract Syntax Tree - Fatal编程技术网

C++ 当涉及多态类型时,如何避免过度使用动态转换/我是否正确地将它们用于AST?

C++ 当涉及多态类型时,如何避免过度使用动态转换/我是否正确地将它们用于AST?,c++,casting,compiler-construction,polymorphism,abstract-syntax-tree,C++,Casting,Compiler Construction,Polymorphism,Abstract Syntax Tree,我已经编写了一个编译器,它以当前的形式工作。但是,在访问AST上的节点时,在区分节点的不同子类时,我觉得我过度使用了动态强制转换。以下是一个例子: 我有一个名为visit的递归方法,它为每个节点子类动态地强制转换一个节点参数。它将检查强制转换是否成功,然后采取适当的措施: VariableValue visit(Node *node) { Num* num = dynamic_cast<Num*>(node); if (num != NULL) { r

我已经编写了一个编译器,它以当前的形式工作。但是,在访问AST上的节点时,在区分节点的不同子类时,我觉得我过度使用了动态强制转换。以下是一个例子:

我有一个名为
visit
的递归方法,它为每个节点子类动态地强制转换一个节点参数。它将检查强制转换是否成功,然后采取适当的措施:

VariableValue visit(Node *node) {
    Num* num = dynamic_cast<Num*>(node);
    if (num != NULL) {
        return visit_Num(num);
    }
    delete num;
    BinOp* binop = dynamic_cast<BinOp*>(node);
    if (binop != NULL) {
        return visit_BinOp(binop);
    }
    delete binop;
    UnOp* unop = dynamic_cast<UnOp*>(node);
    if (unop != NULL) {
        return visit_UnaryOp(unop);
    }
    delete unop;
    ...
下面是如何在解析器中生成节点(例如,
Num
node)


如果所有
节点
都包含一个标识类型的
枚举
,那么为什么不将其与
静态转换
而不是
动态转换
一起使用呢?另外,不相关的,您应该使用
nullptr
而不是
NULL
“我试图通过在强制转换失败时使用delete来改进这一点。”幸运的是,这对您来说不会起任何作用,因为
delete
的目标保证为空指针<代码>动态_cast不会创建新对象;它只是给你一个参考;如果您设法删除了该引用,它将影响原始对象。(顺便说一下,您的基类型似乎没有虚拟析构函数。我想这是因为您没有在摘录中包含它。)这里对“内存”没有影响。CPU,是的……另外,请查看
std::variant
。它更接近您想要的功能。@LightnessRacesBY-SA3.0:可能该注释更明确:-)
class Node {
    public:
        virtual std::string toString() = 0;
        virtual int getNodeAttribute() { return 0; }
        Token token;
        Node(){}
};

class BinOp : public Node{
    public:
        Node *left, *right; 
        Token op;
        BinOp(Node *cleft, Token cop, Node *cright) {
            left = cleft;
            Node::token = cop;
            op = cop;
            right = cright;
        }
        std::string toString() {
            return "BinOp Node";
        }
};

class Num : public Node{
    public:
        TokenValue value;
        Num(Token ctoken) {
            Node::token = ctoken;
            value = ctoken.value;
        }
        std::string toString() {
            return "Num Node";
        }
};

class UnOp : public Node {
    public:
        Node *expr;
        UnOp(Token ctoken, Node *cexpr) {
            Node::token = ctoken;
            expr = cexpr;
        }
        std::string toString() {
            return "UnOp Node";
        }
};

...

Node* Parser::factor() {
    ...
    else if (token.type == TOKENTYPE::INTEGER) {
        eat(TOKENTYPE::INTEGER);
        Num* numNode = new Num(token);
        return numNode;
    }
    ...