C++ 中的列表析构函数

2024-04-05

我刚刚实现了链接列表。它工作得很好,但甚至很难,我已经看到我无法在 Node 上创建工作析构函数的符号,这就是为什么它在代码中未实现。

  1. 我需要在节点上实现工作析构函数
  2. List 的析构函数,但这一个很简单,我将只使用 Node 类的析构函数(但我需要这个)。
  3. 使列表对节点友好,这样我就不必使用 getNext(),但我想我可以 自己处理(不知道如何处理,但我会找出答案)。

请看一下代码,它完全没问题,只要复制它就可以了。

#include <cstdio>
#include <cmath>
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

class Node {
public:
    Node(Node* next, int wrt) {
        this->next = next;
        this->wrt = wrt;
    }

    Node(const Node& obiekt) {
        this->wrt = obiekt.wrt;
        this->next = obiekt.next;
    }
    ~Node() {}

    void show() {
        cout << this->wrt << endl;
    }

    int getWrt(){
        return this->wrt;
    }

    Node* getNext(){
        return this->next;
    }

    void setNext(Node* node){
        this->next = node;
    }

 private:
    Node* next;
    int wrt;
};

class List{
public:
    List(int wrt){
        this->root = new Node(NULL, wrt);
    }

    List(const List& obiekt){
        memcpy(&this->root,&obiekt.root,sizeof(int));
        Node* el = obiekt.root->getNext();
        Node* curr = this->root;
        Node* next;
        while(el != NULL){
            memcpy(&next,&el,sizeof(int));
            curr->setNext(next);
            curr = next;
            next = curr->getNext();
            el = el->getNext();
    /*      curr->show();
            next->show();
            el->show(); */
        }
    }

    void add(int wrt){
        Node* node = new Node(NULL, wrt);
        Node* el = this->root;
        while(el->getNext() != NULL){
            //el->show();
            el = el->getNext();
        }
        el->setNext(node);
    }

    void remove(int index){
        Node* el = this->root;
        if(index == 0){
             //deleting old one
             this->root = this->root->getNext();
        }
        else{
            int i  = 0;
            while(el != NULL && i < index - 1){
            //  el->show();
                el = el->getNext();
                i++;
            }
            if(el!=NULL){
                Node* toRem = el->getNext();
                Node* newNext = toRem->getNext();
                el->setNext(newNext);
                //deleteing old one
            }
        }
    }

    void show(){
        Node* el = this->root;
        while(el != NULL){
            el->show();
            el = el->getNext();
        }
    }

    ~List(){}

private:
    Node* root;
};

int main(){
    List* l = new List(1); //first list
    l->add(2);
    l->add(3);
    l->show();
    cout << endl;

    List* lala = new List(*l); //lala is second list created by copy cosntructor
    lala->show();
    cout << endl;

    lala->add(4);
    lala->remove(0);
    lala->show();

    return 0;
}

我建议你从实现析构函数开始List。由于您通过使用动态分配内存new,你应该使用释放它delete。 (如果您使用new[], 这将是delete[]):

~List()
{
    Node* currentNode = this->root; // initialize current node to root
    while (currentNode)
    {
        Node* nextNode = currentNode->getNext();    // get next node
        delete currentNode;                         // delete current
        currentNode = nextNode;                     // set current to "old" next
    }
}

一旦你有了正确的析构函数,你应该尝试你的复制构造函数是否正确:

List* lala = new List(*l);
delete l; // delete list that was used to create copy, shouldn't affect copy

您会发现您的复制构造函数是错误的,并且还会导致您的应用程序崩溃。为什么?因为目的复制构造函数就是创建一个new对象作为现有对象的副本。你的复制构造函数只是复制指针假设sizeof(Node*)等于sizeof(int)。它应该看起来像这样:

List(const List& list)
{
    // if empty list is being copied:
    if (!list.root)
    {
        this->root = NULL;
        return;
    }

    // create new root:
    this->root = new Node(NULL, list.root->getWrt());

    Node* list_currentNode = list.root;
    Node* this_currentNode = this->root;
    while (list_currentNode->getNext())
    {
        // create new successor:
        Node* newNode = new Node(NULL, list_currentNode->getNext()->getWrt());
        this_currentNode->setNext(newNode);
        this_currentNode = this_currentNode->getNext();
        list_currentNode = list_currentNode->getNext();
    }
}

还有你的功能remove是错误的,因为它“删除”了对某个节点的引用,但从未释放该节点所在的内存。delete应该调用以释放该内存。

“我需要在节点上实现工作析构函数”- 不,你不知道。节点本身不分配任何内存,因此它不应该释放任何内存。节点不应该负责销毁Node* next也不清理存储它的内存。不要实现 Node 的析构函数或复制构造函数。您还想阅读以下内容:什么是三法则? https://stackoverflow.com/q/4172722/1168156

“使列表对 Node 友好,这样我就不必使用 getNext()”- 你想说在 Node 类中,class List is its friend:

class Node
{
    friend class List; // <-- that's it

请注意,您的代码包含的这 5 个标头中只需要一个:<iostream>。 还要注意写using namespace std;在文件的开头被认为是不好的做法因为它可能会导致某些类型的名称变得不明确。在小范围内明智地使用它或使用std::前缀代替。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 中的列表析构函数 的相关文章

随机推荐

  • Verilog 中的大括号是什么意思?

    我很难理解 Verilog 中的以下语法 input 15 0 a 16 bit input output 31 0 result 32 bit output assign result 16 a 15 a 15 0 我知道assign语句
  • 如何获取两个日期之间的天数?

    我需要计算两个日期之间的天数 我已经检查了此链接给出的代码如何使用 JavaScript 计算两个日期之间的天数 https stackoverflow com questions 2627473 how to calculate the
  • 删除名为“NA”的列

    我正在处理一些 RNA seq 计数数据 其中大约有 60 000 列包含基因名称 24 行包含样本名称 当我进行一些基因名称转换时 我留下了一堆名为NA 我知道 R 可以处理NA与典型的列名称不同 我的问题是如何删除这些列 这是我的数据的
  • Chrome 无法获取选定的 html 字符串换行标签 (contenteditable)

    我在用着this https stackoverflow com a 6668159 1491124Tim Down 的解决方案在 contenteditable div 中获取选定的 html 并且工作正常 谢谢 Tim 但是使用 Chr
  • 显示 2 行消息弹出 vba 6

    有没有办法在 vba 6 的弹出窗口上显示 2 或 3 或 4 或 n 行消息 目前我的弹出窗口 调用 MsgBox 函数 显示如下消息 You did something wrong Please enter valid input 我希
  • ES6 箭头函数和 Promise Chaining 精简语法解释

    在下面的代码块中 有人可以提供压缩警报语句语法的链接或解释吗 我理解前面的扩展等效代码已被注释掉并包含消息参数 但是 我找不到省略消息参数的语法参考 let timeoutPromise new Promise resolve reject
  • Pycharm不显示结果

    Pycharm不显示结果 进程已完成 退出代码为 1 但是当我调试它的工作并显示警告时 Debugger speedups using cython not found Run C Python27 python exe C Program
  • C# COM 自动化的双接口和仅调度接口之间的区别

    我正在针对 C COM 服务器实现一个 C COM 客户端 当我将 COM 接口标记为 Dual 时 COM 客户端可以正常工作 但当我删除 Dual 属性时 它会抛出 InvalidCastException 因此 对我来说最简单的解决方
  • PHP 8 严格类型强制应用于本机函数?

    我的代码适用于 PHP 7 round microtime 3 但在 PHP 8 中 致命错误 未捕获类型错误 round 参数 1 num 必须是 int float 类型 4 中给出的字符串堆栈跟踪 0 round 0 21066100
  • 嵌套 ng-repeat 性能

    我听说嵌套 ng repeats 会严重影响 Angular 的性能 如果它会导致大量带有 Angular 表达式的元素 我实际上已经遇到过这种情况 我正在尝试编写一些代码 我尝试使用bindonce https github com Pa
  • R - 从字符串右侧第 n 次出现字符后提取信息

    我见过很多次提取w gsub但它们主要处理从左到右或在一次出现后提取 我想从右到左匹配 数四次出现 匹配第 3 次和第 4 次出现之间的所有内容 例如 string outcome here are some words to try so
  • 在模板化派生类中,为什么需要在成员函数内使用“this->”限定基类成员名称?

    当我调查 Qt 的源代码时 我发现 trolltech 的人明确使用this关键字来访问析构函数上的字段 inline QScopedPointer T oldD this gt d Cleanup cleanup oldD this gt
  • 尽管安装了 Spyder-Terminal,Spyder 5 中仍然没有终端

    我在 Mac OS Big Sur 上安装了 Spyder 5 我从终端运行此命令 conda install spider terminal c spider ide 该命令运行没有错误 仍然没有终端 我一定做错了什么 因为终端没有显示在
  • 使用地图功能

    我遇到了问题map功能 当我想打印创建的列表时 解释器显示指针 gt gt gt squares map lambda x x 2 range 10 gt gt gt print squares
  • 我可以使用 Node.js 阅读 PDF 或 Word 文档吗?

    我找不到任何软件包来执行此操作 我知道 PHP 有大量的 PDF 库 比如http www fpdf org http www fpdf org 但是 Node 有什么用吗 textract https npmjs org package
  • Deno 中子进程如何向父进程发送消息?

    From 这个答案 https stackoverflow com a 62085642 6587634 我知道父进程可以与子进程通信 但是反过来呢 从工人那里你必须使用Worker postMessage https developer
  • SVG 图像在某些 Web 服务器上不显示

    我在某些服务器上的 html 文件中显示 svg 图像时遇到问题 这让我感到困惑 因为我认为是否渲染 svg 图像是由浏览器决定的 但浏览器保持不变 我使用以下字符串来显示它们 img src path to image svg alt i
  • F# 中的全局运算符重载

    我正在开始为笛卡尔积和矩阵乘法定义自己的运算符 将矩阵和向量别名为列表 type Matrix float list list type Vector float list 我可以通过编写自己的初始化代码 并获得笛卡尔积 let inlin
  • pytesseract 错误 Windows 错误 [错误 2]

    您好 我正在尝试使用 python 库 pytesseract 从图像中提取文本 请查找代码 from PIL import Image from pytesseract import image to string print image
  • C++ 中的列表析构函数

    我刚刚实现了链接列表 它工作得很好 但甚至很难 我已经看到我无法在 Node 上创建工作析构函数的符号 这就是为什么它在代码中未实现 我需要在节点上实现工作析构函数 List 的析构函数 但这一个很简单 我将只使用 Node 类的析构函数