Needing a private and public method for the same recursive function

3.2k views Asked by At

We have recently been working on implementing recursive methods for several classes (trees, heaps, queues, linked lists, etc) in C++ for my computer science class. I have not been having any trouble writing the implementations for the methods, but something my professor mentioned briefly in passing confused me and she never elaborated on the point.

She mentioned that when implementing a recursive function for a class you need to have both a public and private version of that function.

For example (part of a linked list class definition):

public: 
  // constructors, destructors
  // member functions etc.
  findMax() { findMax(head); }
private:
  findMax(Node* first_node) { // actual code with recursive calls }
  Node* head;

So here there are two functions, one private and one public. All the public function does is call the private function and return whatever it finds to be the answer.

I have a few questions about this.

Is this something you must do? Does this only apply to class methods that are recursive? If so, what about recursive functions makes this necessary? Would you do this for other functions?

My intuition is that perhaps this is done to ensure that people using the public class methods don't go full dingus mode and end up calling a recursive function with parameters that won't ever lead to a stopping/base case.

Can anyone elaborate on this idea in general and explain it in an intuitive way?

Thanks!

EDIT: Thank you all for your quick answers they have been very helpful! I think I may have misheard my professor and this actually has nothing to do with recursion (though the example she was writing may have been) and is rather just a convention in Object Oriented Programming.

The idea within OOP being that findMax() requires the use of a private class variable (head) to be of use, but would be a handy public function. The private version of findMax(Node* n) then allows a public user to find the max of the list without having the opportunity to access and mess up the private head.

Thanks everyone! Cheers.

2

There are 2 answers

4
πάντα ῥεῖ On BEST ANSWER

"My intuition is that perhaps this is done to ensure that people using the public class methods don't go full dingus mode and end up calling a recursive function with parameters that won't ever lead to a stopping/base case."

Your intuition is right up to some point. head is managed internally with the class, and shouldn't be introduced as a parameter from a caller.

There's no specific relevance to recursion, but rather data encapsulation OOP principles:

head should be managed from the class internally, though a function findMax() should be available in the public class interface. To provide an appropriate internal implementation the search is delegated to a private implementation, which in this case is used recursively. But that doesn't really matter as mentioned.


As for your edits in the question. You should put as much code as possible into the private function, and leave it narrow. I can't see any reason, why your prof put these in the public function.

1
Lightness Races in Orbit On

Is this something you must do?

No.

Does this only apply to class methods that are recursive?

Not even that.

If so, what about recursive functions makes this necessary?

Nothing.

Would you do this for other functions?

Yes, I would. It's a choice you make about organising your code. In general, the functions invoked by my public class member functions are private, unless there's any inherent need for them to also be public.

She mentioned that when implementing a recursive function for a class you need to have both a public and private version of that function.

Assuming this is close to verbatim, your teacher was either wrong or unclear. (It's also possible that she was leaving the element of "choice" for a future lesson; whether this is ethical/reasonable or not is up for debate.)

One might also argue that, in this case, she misled you by giving the two findMax overloads the same name; findMax() and findMax(Head*) are two separate functions and you could have (I would have) called the latter findMaxImpl(Head*), or something like that. Then you will see that recursion doesn't have anything to do with this.

My intuition is that perhaps this is done to ensure that people using the public class methods don't go full dingus mode and end up calling a recursive function with parameters that won't ever lead to a stopping/base case.

Amusingly, your intuition is a lot more sensible here than C++ actually is. :P There is nothing in the language to prevent or even try to prevent "full dingus mode". Not really.