c++ - 带构造函数和析构函数的链表问题

标签 c++ linked-list

嗨 我有一些关于构造函数和析构函数的问题。我有一个列表类,它有两个内部类,一个用于列表节点的私有(private)类,和一个公共(public)迭代器类。

现在针对这个问题,我编写了一个使用内部迭代器类的非成员打印函数。当我使用这个非成员函数时,它将结束调用迭代器的析构函数。它并没有在这里结束,因为出于某种原因它还会调用列表类的析构函数。当我想再次打印列表内容时,这会导致一些问题。

我不明白为什么它也调用列表类析构函数,想知道是否有人可以告诉我这个问题,以及我应该如何解决它。

我已附上与问题相关的所有代码

主要内容

#include <iostream>

#include "sorted_list.h"
#include "iterator.h"
using namespace std;

void list_print(ostream& os, sorted_list list)
{
    sorted_list::iteratorn it(&list);

    while( ! it.iterator_end())
    {
        os <<   "key = " << setw(3) << it.iterator_get_key()   << ", "
        << "value = " << setw(5) << it.iterator_get_value() << endl;
        it.iterator_next();
    }

    os << endl;
}

int main()
{


    sorted_list a;
    a.insert(4,4);
    a.insert(5,5);


    list_print(cout,a);
    list_print(cout,a);
}

排序列表.cc

#include "sorted_list.h"

sorted_list::sorted_list()
{
    cout << "construct sorted_list" << endl;
    this->first = 0;
}
sorted_list::~sorted_list()
{
    cout << "destruct sorted_list" << endl;
    destroy(this->first);

}

void sorted_list::destroy(list_link* item)
{
    cout << "destroy list_link" << endl;
    if(item)
    {
        destroy(item->next);
        delete item;
    }

}

void sorted_list::insert(int key, double value)
{
    list_link *curr;
    list_link *prev = 0;

    curr = first;

    while(curr)
    {
        if(value < curr->value)
            break;

        prev = curr;
        curr = curr->next;
    }
    if(this->first == 0 || prev == 0) //if empty or add first
    {
        //first = create(key, value, this->first);
        first = new list_link(key, value, this->first);
    }
    else if(curr == 0)
    {
        //prev->next = create(key, value, 0);
        prev->next = new list_link(key, value, 0);
    }
    else
    {
        //prev->next = create(key, value, curr);
        prev->next = new list_link(key, value, curr);
    }
}

void sorted_list::remove(my_key_type key)
{
    list_link *curr = first;;
    list_link *prev = 0;

   while(curr)
   {
      if(curr->key == key)
      {
         list_link *remove;

         if(prev == 0)
         {
            first = curr->next;
            delete curr;
            curr = first;
         }
         else
         {
            remove = curr;
            curr = curr->next;
            prev->next = curr;
            delete remove;
         }
         continue;
      }
      prev = curr;
      curr = curr->next;
   }
}


sorted_list::list_link* sorted_list::clone(list_link* item)
{
   list_link* copyItem= new list_link(item->key,item->value,0);
   if(item->next!= 0)

      copyItem->next=clone(item->next);
   return copyItem;
    // ADD YOUR CODE HERE ( 4 well formatted lines in reference solution )

}

void sorted_list::copy(sorted_list* my_this_destination)
{
  if (my_this_destination->first == 0) // copy if empty
  {
      cout << "Copy" << endl;
    //list_destroy(my_this_destination);
    my_this_destination->first = clone(first);
  }
}

double sorted_list::find(int key)
{
    list_link *travel = this->first;
    while(travel)
    {
        cout << travel->key << "==" << key << endl;
        if(travel->key == key)
            return travel->key;

        travel = travel->next;
    }
    return -1;
}

int sorted_list::size()
{
    list_link *travel = this->first;
    int i = 0;
    while( travel )
    {
        travel = travel->next;
        i++;
    }
    return i;
}

排序列表.h

#ifndef _SORTED_LIST_H_
#define _SORTED_LIST_H_

#include <iostream>

#include <iomanip>
using namespace std;

typedef int     my_key_type;
typedef double  my_value_type;

class sorted_list
{

public:
    sorted_list(); 
    ~sorted_list();

    void insert(int key, double value);
    void remove(my_key_type key);
    void copy(sorted_list* my_this_destination);
    void destroy();
    void init(struct my_list* my_this);
    void print();
    void print2();
    double find(int key);
    int  size();

private:
    class list_link // An inner class inside sorted_list
    {
    public:
        list_link (my_key_type key, my_value_type value, list_link* next = 0);
        ~list_link();
        my_key_type key;
        my_value_type value;
        list_link *next;
    };

    list_link* first;
    list_link* clone(list_link* item);
    void destroy(list_link* item);
    // More declarations

public:
    class iteratorn
    {
    public:
        iteratorn();
        ~iteratorn();
        iteratorn(sorted_list *item);
        list_link* list_begin();
        bool iterator_end();
        void iterator_next();
        int iterator_get_key();
        double iterator_get_value();

    private:
        sorted_list::list_link* current;
    };
};


#endif

迭代器.cc

#include "iterator.h"
#include "sorted_list.h"

 sorted_list::iteratorn::iteratorn()
 {
 }
sorted_list::iteratorn::iteratorn(sorted_list *list)
{
    cout << "construct iteratorn" << endl;
    this->current = list->first;
}

sorted_list::iteratorn::~iteratorn()
{
    cout << "destruct iteratorn" << endl;
}

sorted_list::list_link* sorted_list::iteratorn::list_begin()
{
    return current;
}

void sorted_list::iteratorn::iterator_next()
{
  current = current->next;
}

int sorted_list::iteratorn::iterator_get_key()
{
  return current->key;
}

double sorted_list::iteratorn::iterator_get_value()
{
  return current->value;
}

list_link.cc

#include "sorted_list.h"


sorted_list::list_link::list_link(my_key_type key, my_value_type value, list_link* next)
{
    this->key = key;
    this->value = value;
    this->next = next;
}

sorted_list::list_link::~list_link()
{
    cout << "list_link destructor" << endl;
}

最佳答案

您的函数 void list_print(ostream& os, sorted_list list) 通过复制获取一个 sorted_list 参数。一个快速而肮脏的修复(出于性能原因你应该这样做)如下:

void list_print(ostream& os, const sorted_list& list)

现在,您的iteratorn类采用了一个可变 列表,因此这不会像您预期的那样工作。您将有很多方法可以更改以使其工作。

无论如何,您真正的问题是缺少合适的复制构造函数。现在,当您“复制”一个列表时,两者最终共享相同的元素,但是您的析构函数被编写得好像每个列表都拥有自己的节点一样。定义适当的复制操作,它将解决您的问题。

关于如何解决问题的更详尽的帮助:(未经测试)

更改签名:

void list_print(ostream& os, const sorted_list& list);

声明+定义复制构造函数:

sorted_list::sorted_list (const sorted_list& other);

更改 iteratorn 接口(interface)以支持 const sorted_list:

class sorted_list::iteratorn
{
public:
    iteratorn();
    ~iteratorn();
    iteratorn(const sorted_list& list);
    const list_link* list_begin() const;
    bool iterator_end() const;
    void iterator_next();
    int iterator_get_key() const;
    double iterator_get_value() const;

private:
        // You *should* make this `const` but it is not required.
    sorted_list::list_link* current;
};

如您所见,更改非常少,但需要在各个地方应用。

const + 非const 迭代器:

我在此处应用更改是基于您的 iteratorn 当前仅在您的 sorted_list 上定义只读操作这一事实。如果您想支持写访问以允许更改存储在列表节点中的值(从不允许更改键,否则您将不再有排序列表),您应该定义两个 迭代器类。有关详细信息,请参阅 STL 迭代器接口(interface)。

关于c++ - 带构造函数和析构函数的链表问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4118171/

相关文章:

php - 如何对类似于链表的条目进行排序?

java - 将对象添加到 LinkedList java 数组

c++ - 私有(private)继承和组合,哪个最好,为什么?

c++ - C 字符串在 C++ 的显式构造函数中赋值?

c++ - 数组索引与数组元素

c++ - 错误 : no matching function for call to ‘sipqt_gui_cpp_RosPluginlibPluginProvider_ForPlugins::connectNotify(const char*&)’

c++ - 为什么 CMakeLists 文件需要位于 CLion 项目文件夹的根目录中?

linux - 如何使用 <sys/queue.h> 功能对列表进行排序?

java - 如何用 switch 语句替换嵌套的 if 语句?

c - C 语言的刽子手控制台游戏