我需要在我的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(我的意思是处理可访问性问题)? 我个人认为结构适合这类任务。
我发布了来自任意项目的代码,但您可能会看到这种做法(带有封装破解方法的类)经常出现。
答案 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
仅适用于某些数据类