我认为你的做法是错误的,你应该首先考虑课堂的外观和感觉,然后考虑里面发生了什么。当我考虑将代码放入一个类中时,特别是处理类似列表的代码时,我首先制作一个类需要支持的操作(追加、擦除、查找?、索引?)的心理列表。然后,我开始考虑我希望类具有的接口。然后,将代码放入类通常是一小步,因为大部分已经由前面的两个步骤决定了。
查看您的代码,我看到返回值仅用于next
在递归调用后重置前一个元素的指针。因此,您可以将该功能一分为二,供列表的用户使用,另一种仅供内部使用。这一点很重要,因为这意味着类的接口只需要向外部(“公共”)显示类用户的接口。它在内部做的是自己的事情。这允许您将其从递归更改为迭代(这将更有效),而不会打扰类的用户。
现在,在您的情况下,您有一个要放入课程的列表。您可以从列表中删除元素,您可以在其中通过地址指定元素。这不会破坏元素,而是将其留给调用者(原始指针总是询问所有权问题,但这是一个不同的问题)。其他任何事情对我来说都是未知的,例如如何填充列表或如何分配节点。这给了我这个擦除操作的用例:
List l;
... // fill l
Node* n = ... // some node
l.erase(n);
delete n;
对于列表类型,这看起来像这样:
struct List
{
void erase(Node* n)
{
m_head = doErase(m_head, n);
}
private:
static Node* doErase(Node* head, Node* node)
{
... // your function here
}
Node* m_head;
};
请注意,仍然缺少一些东西,特别是您想让您的类不可复制,并且您必须决定当节点为空(例如assert(n);
in erase()
)或不在列表中(throw invalid_argument("node not element of list");
in do_erase()
)时要做什么。但是,我希望这可以帮助您入门。