同一个递归函数需要一个 private 和 public 方法

Needing a private and public method for the same recursive function

我们最近一直在为我的计算机科学 class 在 C++ 中实现几个 classes(树、堆、队列、链表等)的递归方法。我在编写这些方法的实现时没有遇到任何问题,但我的教授顺便提到的一些事情让我感到困惑,她从未详细说明这一点。

她提到,在为 class 实现递归函数时,您需要同时拥有该函数的 public 和私有版本。

例如(链表class定义的一部分):

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

所以这里有两个函数,一个是私有的,一个是public。 public 函数所做的就是调用私有函数和 return 它发现的答案。

我对此有一些疑问。

这是你必须要做的事情吗? 这仅适用于递归的 class 方法吗?如果是这样,递归函数如何使这成为必要?您会为其他功能执行此操作吗?

我的直觉是,这样做可能是为了确保使用 public class 方法的人不会进入完整的 dingus 模式,并最终调用一个参数不正确的递归函数曾导致 stopping/base 案例。

任何人都可以概括地阐述这个想法并以直观的方式解释它吗?

谢谢!

编辑:感谢大家的快速回答,他们非常有帮助!我想我可能听错了我的教授,这实际上与递归无关(尽管她写的例子可能是),而只是面向对象编程中的约定。

OOP 中的想法是 findMax() 需要使用私有 class 变量(head)才能使用,但会是一个方便的 public 函数。 findMax(Node* n) 的私有版本允许 public 用户找到列表的最大值,而没有机会访问和弄乱私有头。

谢谢大家!干杯。

"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."

你的直觉在某种程度上是正确的。 head 通过 class 在内部进行管理,不应作为调用者的参数引入。

与递归没有具体关系,而是数据封装OOP原则:

head 应该在内部从 class 进行管理,尽管函数 findMax() 应该在 public class 界面中可用。为了提供适当的内部实现,搜索被委托给 private 实现,在这种情况下递归使用。但这并不像提到的那样重要。


至于你对问题的修改。您应该将尽可能多的代码放入 private 函数中,并使其变窄。我看不出任何原因,为什么你的教授将这些放在 public 函数中。

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?

是的,我愿意。这是您对组织代码做出的选择。一般来说,我的 public class 成员函数调用的函数是 private,除非有任何内在需要它们也是 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.

假设这接近逐字逐句,您的老师要么错了,要么不清楚。 (也有可能她将 "choice" 的元素留到以后的课程中使用;这是否是 ethical/reasonable 有待商榷。)

有人可能还会争辩说,在这种情况下,她通过给两个 findMax 重载赋予相同的名称来误导您; findMax()findMax(Head*) 两个独立的函数 ,您可以(我会)将后者称为 findMaxImpl(Head*),或类似的名称。然后你会发现递归和这个没有任何关系。

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.

有趣的是,您的直觉在这里比 C++ 实际上更明智。 :P 语言中没有任何东西可以阻止甚至 try 可以阻止 "full dingus mode"。不是真的。