C ++中的抽象语法树:类与结构

时间:2017-01-01 20:50:28

标签: c++ oop abstract-syntax-tree encapsulation getter

我需要在我的C ++程序中表示树层次结构(精确的AST)。好吧,我多次看到过这种结构的例子,但有一点我不清楚。请告诉我为什么在C ++中使用类而不是结构来生成AST是如此常见?例如,请考虑此代码,它代表AST的节点:

class Comparison {
public:
  Node* getLhs() const { return m_lhs; }
  Node* getRhs() const { return m_rhs; }

  //other stuff
private:
  ComparisonOperator m_op;
  Node* m_lhs;
  Node* m_rhs;
};

(它的灵感来自https://github.com/clever-lang/clever/blob/master/core/ast.h#L150,但我已经抛弃了一些不必要的细节) 正如你在这里看到的,我们有两个getter返回指向私有数据成员的指针,那些指针甚至不是const!正如我所听到的那样打破封装。那么为什么AST节点的结构(默认情况下所有成员都是公共的)呢?你将如何在C ++中实现AST(我的意思是处理可访问性问题)? 我个人认为结构适合这类任务。

我发布了来自任意项目的代码,但您可能会看到这种做法(带有封装破解方法的类)经常出现。

3 个答案:

答案 0 :(得分:3)

  

请告诉我为什么在C ++中使用类而不是结构来生成AST是如此常见? [..] 我个人认为结构很适合这些任务。

没关系; C ++没有结构。当你写struct时,你正在创建一个类。

struct或写class。然后写public或写private

有些人选择class,因为他们认为使用struct定义的类不能包含私有成员,成员函数等。他们错了。

有些人会选择class,因为他们只是希望将struct置于“简单”类型之后,没有私人成员或成员函数,纯粹是出于样式原因。这是主观的,完全取决于他们。 (我主要是自己做类似的事情。)

该标准确实在很少的地方使用术语“结构”和“结构”,有时显然是作为引用POD类的捷径,但其他时候错误的(例如C ++14§C.1.2/ 3.3“结构是一个类”)。这导致一些人质疑C ++没有结构的事实(包括暗示“结构”是类的一个子集,尽管这个概念还没有很好地定义为正式接受)。无论如何,std::is_class特征的行为使事情变得非常明确。

答案 1 :(得分:0)

也许类似以下的东西是可接受的模式?

class Comparison {
public:
  const Node* lhs() const { return m_lhs; }
  const Node* rhs() const { return m_rhs; }
  Node* mutable_lhs() const { return m_lhs; }
  Node* mutable_rhs() const { return m_rhs; }

  //other stuff
private:
  ComparisonOperator m_op;
  Node* m_lhs;
  Node* m_rhs;
};

如果程序员打算获得一个可变的节点,那么至少他的意图是明确的吗?

即使使用mutable_lhs(),他也只能获得指向可变节点的指针,但他仍然无法更改指针本身。如果在没有明确的公共/私人规范的情况下使用struct,他将失去这种保护。

答案 2 :(得分:0)

好吧,请考虑以下代码:

class Parent {
public:
    int x;
    void test();

private:
    int y;
};

class Child : public Parent {
public:
    int z;
};

现在与struct关键字相同:

struct Parent {
    int x;
    void test();

private:
    int y;
};

struct Child : Parent {
    int z;
};

有些人更喜欢使用class关键字来表明某些内容是某个类,而struct仅适用于某些数据类