2017-09-16 123 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) { 
    ... 
} 

它使用重载,而不是默认参数,并完成或多或少同样的事情。