2017-01-01 199 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的啓發,但我已經扔掉了一些不必要的細節) 正如你在這裏看到我們有兩個干將其返回指針私人數據成員和那些指針甚至不是常量!正如我聽說的那樣封裝了封裝。那麼爲什麼沒有AST節點的結構(所有成員都是默認公開的)呢?你將如何在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; 
}; 

如果程序員打算得到一個可變的節點,那麼至少他會讓他的意圖清楚嗎?

順便說一句,即使與mutable_lhs()他只獲得指向一個可變節點的指針,但他仍然不會改變指針本身。如果使用沒有明確公/私規範的結構,他會失去這種保護。

+0

*「如果使用struct,他會失去這種保護。」* - 這是怎麼回事? – UnholySheep

+1

@UnholySheep:'obj.m_lhs = nullptr'將失去原始節點。相反,'obj.mutable_lhs()= nullptr'將是無害的(&無用的)。 – Edy

+0

這是一個'public'與'private' + getters的問題 - 它不是'struct'與'class'的問題。如果我只是用代碼中的'struct'替換'class'關鍵字,那麼它不會讓它更安全。 – UnholySheep

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特徵的行爲使事情變得非常清楚。

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對於一些數據只有類