C++ 如何将指针函数转换为类函数?c++;

C++ 如何将指针函数转换为类函数?c++;,c++,class,linked-list,C++,Class,Linked List,我有这个删除功能: Node* deleteNode(Node *head, Node *node) { if (head != 0) { if (head == node) head = head->next; else head->next = deleteNode(head->next, node); } return head; } 但为了更清楚地说明这一点

我有这个删除功能:

Node* deleteNode(Node *head, Node *node)
{
    if (head != 0)
    {
        if (head == node)
            head = head->next;
        else
            head->next = deleteNode(head->next, node);
    }
    return head;
}
但为了更清楚地说明这一点(因为我的程序的其余函数都在一个类中),我想将其表示为:

void List::deleteNode()
{
    //the code comes here
}
(我想从单链表的开头删除,不想使用库。)

类似于

void List::deleteNode()
{
    /* I suppose you have Node *head in your List class */
    if(head == NULL)
        return;

    Node * temp = head;
    head = head -> next;

    delete temp;
}
我认为“deleteHead”是这个函数更好的名称

void List::deleteNode()
{
    /* I suppose you have Node *head in your List class */
    if(head == NULL)
        return;

    Node * temp = head;
    head = head -> next;

    delete temp;
}

我认为“deleteHead”是这个函数的一个更好的名称。

我认为您的做法是错误的,您应该首先考虑类的外观和感觉,然后考虑其中的内容。当我考虑将代码放入类中时,特别是处理列表之类的代码,我首先列出类需要支持的操作(append、erase、find?、index?)。然后,我开始考虑我希望类具有的接口。然后,将代码放入类中通常是一小步,因为大部分代码都已经由前面的两个步骤决定

查看您的代码,我发现返回值仅用于在递归调用后重置上一个元素的
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;
};

请注意,仍然缺少一些内容,特别是您希望使类不可复制,并且您必须决定当节点为null(例如
assert(n);
erase()
)中的
或不在列表中时该怎么办(
抛出无效的_参数(“node not list元素”);
do_erase()
)。但是,我希望这会让你开始。

我认为你的做法是错误的,你应该首先考虑课堂的外观和感觉,然后再考虑其中的内容。当我考虑将代码放入类中时,特别是处理列表之类的代码,我首先列出类需要支持的操作(append、erase、find?、index?)。然后,我开始考虑我希望类具有的接口。然后,将代码放入类中通常是一小步,因为大部分代码都已经由前面的两个步骤决定

查看您的代码,我发现返回值仅用于在递归调用后重置上一个元素的
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;
};

请注意,仍然缺少一些内容,特别是您希望使类不可复制,并且您必须决定当节点为null(例如
assert(n);
erase()
)中的
或不在列表中时该怎么办(
抛出无效的_参数(“node not list元素”);
do_erase()
)。但是,我希望这能让您开始。

您的问题不是很清楚-您是否实现了自己的列表类?如果是这样,只需将指向第一个节点的指针作为类中的成员。但是,您始终必须至少传入一个参数(您要删除的节点)。他写了“我想从头开始删除”,因此不需要任何参数,尽管函数名有误导性。您的问题不是很清楚-您是否实现了自己的列表类?如果是这样,只需将指向第一个节点的指针作为类中的成员。但是,您始终必须至少传入一个参数(您要删除的节点)。他写了“我想从头开始删除”,因此不需要任何参数,尽管函数名有误导性。哦,谢谢!如果我想删除头部和下面的节点呢?我想我需要争论。你可以删除两次头。哦,谢谢!如果我想删除头部和下面的节点呢?我想我需要辩论。你可以删除两次头。