2017-09-16 140 views
1
class BinarySearchTree 
{ 
private: 
    Node *root; 
public: 
    BinarySearchTree() ; 
    ~BinarySearchTree(); 
    void insert_node(int, Node*); 
    void print_tree(Node *); 
    friend Node* get_root(); 

}; 

/**********************BinarySearchTree definition***************/ 
BinarySearchTree::BinarySearchTree() : root(nullptr) 
{ 

} 

Node* get_root() 
{ 
    Node* x= root; 
    return x; 
} 

編譯器說,error C2065: 'root' : undeclared identifier 爲什麼不能編譯器識別root雖然get_root是朋友的功能?訪問私有成員變量沒有對象

同樣,爲什麼我不能使用這樣的默認參數?

void BinarySearchTree::insert_node(int inserted_key,Node* traverse_ptr = root); 
+0

我向你推薦'BinarySearchTree'和'Node'是同一件事,而不是兩件不同的事情。任何'Node'實際上都是BST的根。 – EJP

回答

1

對於你的問題有關get_root,編譯器足夠聰明來確定get_rootBinarySearchTree的朋友。這不是問題。相反,當編譯器看到這條線,它不知道哪個對象BinarySearchTree你問它來讀取根:它

Node* x = root; 

這樣的想法 - 友元函數是一個免費的功能,就像任何其他自由函數一樣,除了它可以讀取私有字段。但是,爲了讀取BinarySearchTree對象的私有字段,它需要有一個實際的,誠實善良的BinarySearchTree對象來讀取該字段。

這沒有提出成員函數,因爲成員函數隱式地相對於某個接收者對象進行操作。在BinarySearchTree的成員函數中,如果您談到root,C++將其解釋爲「this對象的root字段」。

鑑於你想要在這裏做什麼,我認爲你應該使get_root成爲一個成員函數而不是朋友函數。你也可以改變get_root因此,它需要一個BST作爲輸入:

Node* get_root(const BinarySearchTree& bst) 
{ 
    return bst.root; 
} 

你問爲什麼你不能給默認參數是這樣一個單獨的問題:

void BinarySearchTree ::insert_node(int inserted_key, Node* traverse_ptr = root); 

的C++規範只是普通的不允許您將成員變量用作成員函數的默認值。我認爲這與實現問題有關,如果您使用多重繼承,那麼指向對象的指針可能指向對象的中間,並且無法靜態地知道字段的偏移量。

然而,你可以通過做這樣的事情解決這個問題:

class BinarySearchTree { 
public: 
    void insert_node(int inserted_key); 
    void insert_node(int inserted_key, Node* traverse_ptr); 
} 

void BinarySearchTree::insert_node(int inserted_key) { 
    insert_node(inserted_key, root); 
} 

void BinarySearchTree::insert_node(int inserted_key, Node* traverse_ptr) { 
    ... 
} 

它使用重載,而不是默認參數,並完成或多或少同樣的事情。