如何处理成员函数中的递归?

例如,我有一个empty函数来清除链表:

void empty(Node* head) {
        if (head->next) { empty(head->next); }
        delete head;
        head = nullptr;
    }

但后来我为链表创建了一个类,所以现在不需要传递head参数:

void empty() {
        if (head->next) { empty(head->next); }
        delete head;
        head = nullptr;
    }

但是empty(head->next)行显然是错误的,因为empty不接受任何参数。我的想法是在函数中创建一个函数(使用lambda),类似于:

void empty() {
        std::function<void(Node*)> emptyWrapper = [&] (Node* l_head) {
            if (l_head->next) { emptyWrapper(l_head->next); }
            delete l_head;
            l_head = nullptr;
        };
        emptyWrapper(head);
    }

但我想知道有没有更好的办法。最近,Lambdas对我来说是一种理想的固定方式。


解决方案

一般方法是声明公共成员函数,该成员函数又调用私有静态递归成员函数。

请注意,名称empty听起来令人困惑。最好将函数命名为clear

给您

#include <functional>

//...

class List
{
public:
    //...
    void clear() 
    {
        clear( head );
    }

private:
    static void clear( Node * &head )
    {
        if ( head )
        {
            delete std::exchange( head, head->next );
            clear( head ); 
        }
    }
    //...
}

无需定义辅助静态函数即可使用相同的方法。

void clear()
{
    if ( head )
    {
        delete std::exchange( head, head->next );
        clear();
    }
}

这里是一个演示程序。

#include <iostream>
#include <iomanip>
#include <functional>

template <typename T>
class List
{
private:
    struct Node
    {
        T data;
        Node *next;
    } *head = nullptr;

public:
    void push_front( const T &data )
    {
        head = new Node { data, head };
    }

    friend std::ostream & operator <<( std::ostream &os, const List &list )
    {
        for ( Node *current = list.head; current; current = current->next )
        {
            os << current->data << " -> ";
        }

        return os << "null";
    }

    bool empty() const { return head== nullptr; }

    void clear()
    {
        if ( head )
        {
            delete std::exchange( head, head->next );
            clear();
        }
    }
};

int main() 
{
    List<int> list;

    const int N = 10;

    for ( int i = N; i != 0; )
    {
        list.push_front( i-- );
    }

    std::cout << list << '
';

    list.clear();

    std::cout << "list is empty " << std::boolalpha << list.empty() << '
';

    return 0;
}

程序输出为

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
list is empty true

相关文章