访问没有对象的私有成员变量

时间:2017-09-16 23:23:59

标签: c++ friend default-arguments

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

1 个答案:

答案 0 :(得分:1)

关于get_root的问题,编译器非常聪明,可以确定get_rootBinarySearchTree的朋友。这不是问题所在。相反,当编译器看到这一行时,它不知道你要求它从哪个BinarySearchTree对象读取根目录:

Node* x = root;

以这种方式思考 - 友元函数是一个自由函数,就像任何其他自由函数一样,除了它可以读取私有字段。但是,为了读取BinarySearchTree对象的私有字段,它需要有一个实际的,诚实的,良好的BinarySearchTree对象来从中读取字段。

这没有提供成员函数,因为成员函数隐式地相对于某个接收器对象进行操作。在BinarySearchTree的成员函数中,如果您谈到root,C ++会将其解释为“root对象的this字段。”

考虑到你在这里尝试做什么,我认为你应该让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) {
   ...
}

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