Shashank Garg
Shashank Garg

Reputation: 733

Can I use a member element as the default argument for a method of the class?

The method Minimum returns the minimum element in the binary search tree. If no argument is passed it prints the minimum of calling object. If address of a node is passed it prints the minimum of the subtree whose root is node

When compiled it shows "Invalid use of non static data member 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;
}

Upvotes: 4

Views: 145

Answers (4)

No, you cannot.

For the default value you can use either a value, a variable or a function that is accessible in the context of the function definition that is, in the class definition, which is outside of any particular object's context.

It usually helps me thinking on how the compiler really processes this. In particular, when the compiler does overload resolution for a function and finds an overload that has more arguments than those used at the place of call, the compiler will generate code at the place of call to fill in the rest of the arguments. The generated code will always generate a call with all of the arguments:

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

When the compiler processes [1] and it does overload resolution it finds that void ::f(int x = g()) is the best candidate and picks it up. It then fills the default argument and generates the call for you:

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

If you consider a call to a member function, or a member variable of the class, it would not make sense in the context of the caller (the language could be changed to adapt to this, it is not impossible to handle that, but with the current model it does not work).

Upvotes: 3

Michelle
Michelle

Reputation: 2900

If the case where an argument of NULL is explicitly passed doesn't need to be differentiated from no argument being passed, you could set NULL as the default and use root if curnode is 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;
}

Upvotes: 0

Appleshell
Appleshell

Reputation: 7388

You can alternatively set it to NULL for example as default, and then check and set it to the member in the method.

Or overload the method with void Minimum(); and in that method call the one with an argument with the member.

void Tree::Minimum() {
    Minimum(root);
}

Upvotes: 2

Neil Kirk
Neil Kirk

Reputation: 21773

I couldn't find any way to get the default parameter to work like that. But you can get the same result by overloading the function, like so:

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

Upvotes: 1

Related Questions