4

该方法Minimum返回二叉搜索树中的最小元素。如果没有传递参数,它会打印调用对象的最小值。如果传递了节点的地址,则打印其根为节点的子树的最小值

编译时显示“无效使用非静态数据成员Tree::root

#include<stdlib.h>
#include<iostream>
class Node
{
public:
    Node *leftchild;
    Node *rightchild;
    Node *parent;
    int info;
};

class Tree
{
public:
    Node *root;
    Tree()
    {
        root=NULL;
    }
    void Minimum(Node*);
};

void Tree::Minimum(Node *curnode=root)
{
    Node *parent;
    while(curnode!=NULL)
    {
        parent=curnode;
        curnode=curnode->leftchild;
    }
    std::cout<<parent->info<<endl;
}

int main()
{
    Tree tree;
    tree.Minimum();
    return 0;
}
4

4 回答 4

3

你不能。

对于默认值,您可以使用在函数定义的上下文中可访问的值、变量或函数,即在类定义中,在任何特定对象的上下文之外。

它通常可以帮助我思考编译器如何真正处理它。特别是,当编译器对函数进行重载解析并发现一个重载的参数比调用处使用的参数多时,编译器将在调用处生成代码以填充其余参数。生成的代码将始终使用所有参数生成一个调用:

int g();
void f(int x = g()); 
int main() {
    f();               // [1]
}

当编译器处理 [1] 并进行重载解析时,它会发现这void ::f(int x = g())是最佳候选并选择它。然后它填充默认参数并为您生成调用:

int main() {
    f( /*compiler injected*/g() );
}

如果您考虑对成员函数或类的成员变量的调用,则在调用者的上下文中是没有意义的(可以更改语言以适应这一点,并非不可能处理,但是当前模型不起作用)。

于 2013-08-23T15:00:58.433 回答
2

您也可以将其设置NULL为例如默认值,然后检查并将其设置为方法中的成员。

或者使用该方法重载该方法,void Minimum();并在该方法中调用带有成员参数的方法。

void Tree::Minimum() {
    Minimum(root);
}
于 2013-08-23T14:55:24.047 回答
1

我找不到任何方法让默认参数像那样工作。但是你可以通过重载函数得到相同的结果,如下所示:

class Tree
{
public:
    Node *root;
    Tree()
    {
        root=NULL;
    }
    void Minimum(Node*);
    void Minimum();
};

void Tree::Minimum(Node *curnode)
{
    Node *parent;
    while(curnode!=NULL)
    {
        parent=curnode;
        curnode=curnode->leftchild;
    }
    std::cout<<parent->info<<std::endl;
}

void Tree::Minimum()
{
    Minimum(root);
}
于 2013-08-23T14:54:56.003 回答
0

如果NULL不需要将显式传递的参数与不传递参数的情况区分开来,则可以将其设置NULL为默认值并使用rootif curnodeis NULL

void Tree::Minimum(Node *curnode=NULL)
{
    if (curnode==NULL)
        curnode = root;
    Node *parent;
    while(curnode!=NULL)
    {
        parent=curnode;
        curnode=curnode->leftchild;
    }
    std::cout<<parent->info<<endl;
}
于 2013-08-23T14:56:21.550 回答