2017-01-01 9 views
1

내 C++ 프로그램에서 트리 계층 구조 (정확한 AST)를 나타내야합니다. 좋아, 나는 여러 번 그러한 구조의 예를 보았지만 한 가지는 나에게 불명확하다. C++에서 AST를 구조체 대신 클래스를 사용하는 것이 왜 그렇게 흔한 지 말해 주시겠습니까? 예를 들어, AST의 노드를 나타내는이 코드를 고려 :C++의 추상 구문 트리 : 클래스와 구조체

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에서 영감을하지만 불필요한 세부 사항을 멀리 던져) 당신이 여기에서 보는 것처럼 우리가 포인터를 돌려 두 게터가 개인 데이터 멤버와 포인터도 const가 아닙니다! 내가 들었을 때 캡슐화가 깨졌습니다. 그렇다면 AST 노드의 구조체 (모든 멤버가 기본적으로 public 인 구조체)를 사용하지 않는 이유는 무엇입니까? C++에서 AST를 어떻게 구현하겠습니까? (접근성 문제를 다루는 것을 의미합니까?) 개인적으로 구조체가 그러한 작업에 적합하다고 생각합니다.

임의의 프로젝트에서 코드를 게시했지만이 연습 (AST의 캡슐화 방법이있는 클래스)은 다소 자주 볼 수 있습니다.

+2

나는 실제 응답이 아니라 의견 기반의 대답이라고 말할 것입니다. – skypjack

+1

귀하의 질문은 실제로 AST에 관한 것이 아니라 개체에 숨겨진 개인 회원을 갖는 것이 좋은지 여부입니다. –

+2

이런 종류의 게이머는 왜 그런 게터가 좋지 않은지에 대해 격찬하기 시작합니다. 그러나 나는 자제 할 것이다. 그것은 매우 의견을 기반으로합니다. – DeiDei

답변

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; 
}; 

프로그래머가 변경할 수있는 노드를 얻으려는 경우 적어도 의도를 분명히합니다.

BTW 심지어 mutable_lhs()과 함께 그는 변경 가능한 노드에 대한 포인터 만 가져 오지만 그는 여전히 포인터 자체를 변경하지 않습니다. 명시적인 public/private 사양없이 struct를 사용하면 보호 기능을 잃게됩니다.

+0

* "구조를 사용하면 보호 기능을 잃을 것입니다."* - 어떻게 그렇게? – UnholySheep

+1

@UnholySheep :'obj.m_lhs = nullptr'은 원래 노드를 잃어 버립니다. 대조적으로,'obj.mutable_lhs() = nullptr'는 무해합니다. – Edy

+0

그건'public' 대'private' + getters의 문제입니다.'struct'와'class'의 문제가 아닙니다. 방금'class' 키워드를 코드에서'struct'로 대체했다면 덜 안전하지 않을 것입니다. – UnholySheep

3

C++에서 AST 용 구조체 대신 클래스를 사용하는 이유는 무엇입니까? [..] 개인적으로 구조체가 이러한 작업에 적합하다고 생각합니다.

중요하지 않습니다. C++에는 구조체가 없습니다 & dagger;. struct으로 작성하면 수업을 생성하게됩니다.

struct으로 작성하거나 class으로 작성하십시오. 그런 다음 public을 작성하거나 private으로 작성하십시오.

어떤 사람들은 struct을 사용하여 정의 된 클래스에는 개인 멤버, 멤버 함수 등을 포함 할 수 없다고 생각하기 때문에 class을 선택하는 사람들이 있습니다. 그들은 틀렸다.

일부 사람들은 을 개인 회원이나 회원 기능이없는 "단순한"유형으로 유지하는 것을 선호하기 때문에 스타일을 이유로합니다. 그것은 주관적이고 전적으로 그들에게 달렸습니다. (내가 대부분은와 비슷한 일을한다.)

& dagger; 표준에서는 POD 클래스를 참조하기위한 지름길로, 때때로 다른 곳에서는 "C++ 14 §C.1.2/3.3 "구조체는 클래스입니다"). 이로 인해 어떤 사람들은 C++에 구조체가 없다는 사실에 의문을 갖게되었습니다. (이 구조체는 공식적으로 받아 들여지기에 충분하지 않다고하더라도 "구조체"가 클래스의 하위 집합임을 암시하는 것을 포함하여). 그럼에도 불구하고 std::is_class 특성의 동작은 상황을 분명하게 만듭니다.이제

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

private: 
    int y; 
}; 

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

구조체 키워드와 같은 일 :

0

음,이 코드를 고려

struct Parent { 
    int x; 
    void test(); 

private: 
    int y; 
}; 

struct Child : Parent { 
    int z; 
}; 

일부가 뭔가 클래스임을 명확하게하기 위해 class 키워드를 선호, 그리고 struct 일부 데이터 전용 클래스의 경우