【问题标题】:How can I assign the "this" pointer as "temp"?如何将“this”指针分配为“temp”?
【发布时间】:2020-08-18 07:35:37
【问题描述】:

我调用了一个函数interleave,看起来像

void AddressLinkedList::interleave(AddressLinkedList& other) {
    AddressLinkedList temp;
    AddressListNode* thisCur = this->head;
    AddressListNode* otherCur = other.head;
    for (int i = 0; i < this->length + other.length; i++) {
        if (i % 2 == 0) {
            temp.insertEnd(thisCur->data);
            thisCur = thisCur->next;
        }
        else if (i % 2 != 0) {
            temp.insertEnd(otherCur->data);
            otherCur = otherCur->next;
        }
    }
    return;
}

这个函数应该按照如果 A 看起来像 "1, 2, 3" 而 B 看起来像 "4, 5, 6" 的方式将单链表 A 和单链表 B 交织在一起,那么调用linkedListA.interleave(linkedListB) 应该使 A "1, 4, 2, 5, 3, 6"。我已经成功地创建了一个这样的列表,问题是它是 temp 列表,但我不知道如何制作它,所以它将是带有最终目标 linkedListAthis 指针是前面提到的“单链表A”。如果重要的话,下面是重载的赋值运算符和insertEnd 函数。

void AddressLinkedList::insertEnd(const Address& value) {
    if (length == 0) {
        this->insertStart(value);
        return;
    }
    AddressListNode* temp = new AddressListNode(value);
    length++;
    tail->next = temp;
    tail = temp;
}
AddressLinkedList& AddressLinkedList::operator=(const AddressLinkedList& other) {
    delete this;
    AddressListNode* current;
    current = other.head;
    while (current != nullptr) {
        insertEnd(current->data);
        current = current->next;
    }
    return *this;
}

【问题讨论】:

  • 列表B呢?函数执行后是否为空?
  • 列表 B 中还有项目也没关系。
  • 为什么参数不是常量引用?
  • 这可能只是我们的讲师给我们的起始函数声明错误,作业明确指出您不必从other中删除项目
  • “这是临时列表,但我不知道如何制作它,所以它会是 this 指针”——这用词很奇怪。我认为您的意思是“这是临时列表,但我不知道如何制作它,所以它将是 *this”,因为 this 指向的对象是当前对象。 (这与delete this;在您的赋值运算符中绝对错误的原因有关。如果您要删除应该接收赋值的对象,您将不再有对象来接收赋值。)

标签: c++ linked-list interleave


【解决方案1】:

由于interleave 被定义为AddressLinkedList 的成员函数,它应该修改(并处理)它被调用的对象。因此,您不需要(也不应该)创建一个临时列表来使用它来构建您的结果集合,然后将其“分配”为this。可能有一些newdeleteraw pointer 诡计,但我不建议这样做(想法是创建AddressListNode* 作为头部,然后将新头部分配到原来的位置,但是您还必须从原始头部删除以前的 AddressListNode* 链以避免内存泄漏,正如我所说,不推荐)。

假设您调用此方法的代码如下所示:

AddressLinkedList A;
AddressLinkedList B;
... //inserting values to A and B
A.interleave(B);

您的interleave 实现应该看起来更像这样(它更多的是对概念的证明,而不是可行的解决方案,我没有编译它):

void AddressLinkedList::interleave(AddressLinkedList& other) {
    AddressListNode* thisCur = head;
    AddressListNode* otherCur = other.head;
    while (thisCur != nullptr) { //assumig that last node points to nullptr
        AddressListNode* nextNode = thisCur->next;
        AddressListNode* otherNext = otherCur->next;
        thisCur->next = otherCur; //attach it to node from other
        thisCur = thisCur->next; //advance to next node
        thisCur = nextNode; //reattach node that was originally after current
        thisCur = thisCur->next; //advance again to next node
        otherCur = otherNext ; //advance on other
    }
    other->head = nullptr; //loop above hijack nodes from other
}

所有这些代码所做的就是,它需要你的两个集合的头,迭代this,并为每个节点附加来自other的相应节点。实际上,它将修改您最初调用 interleave 方法的对象。但是,由于修改了AddressListNode 指针,它还会破坏您传递给interleave 的原始AddressLinkedList 和参数。所以你可能应该修改它,让thisCur-&gt;next = otherCur; 实际上创建一个Address 的副本并创建新节点。

【讨论】:

  • 当我运行它时,由于某种原因,在this-&gt;head 之后,它使列表 A “1、4、5、6”,每次都在列表 A 的“头”之后附加 otherCur将它们交织在一起。
  • 不想成为那个卑鄙的人,但正如我所说,这更像是一种概念证明。毕竟这是你的任务,所以附上调试器,一步一步去,找出问题所在。我只是想给你指出正确的方向。请记住,我所写的示例是正确的方法。
  • 我在示例中修复了一个错误,现在它应该可以正常工作了。但是它仍然会从other 劫持节点,您应该创建适当的节点并将Address 分配给它们,类似于在insertEnd 中的操作。
猜你喜欢
  • 2016-08-06
  • 2014-01-31
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 2018-11-26
  • 2014-04-07
  • 1970-01-01
  • 2013-05-31
相关资源
最近更新 更多