2

私は現在 C++ を独学しており、C++ で部分的に完成したポインターを使用して二重リンク リストを実装しようとしています。現在、コードがダングリング ノードまたは出力エラーの処理に失敗していることは承知しています。どちらも次に実装します。ただし、コードは少なくともリスト オブジェクトを作成し、それに要素を追加できる必要があります。現在、リストのコンストラクターを呼び出そうとするとエラーが発生します。これは、LinkedList* から非スカラー型の LinkedList への変換を要求していることを示しています。リストがポインタとして宣言されているのはなぜですか? どんな助けでも大歓迎です、ありがとう!

LinkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H

struct dataElement {
  int key;
  int id;
};

struct Node
{
    dataElement data;
    Node* next;
    Node* prev;
};


class LinkedList
{
public:
    /** Default constructor */
    LinkedList();
    /** Default destructor */
    virtual ~LinkedList();
    void addAtFront(int newElement);
    void addAtBack(int newElement);
    int removeTop();
    int removeBottom();
    int getTop();
    int getBottom();
    int findKey(int keyToFind);
protected:
private:
    Node* head;
    Node* tail;
    int size;
};

#endif // LINKEDLIST_H


LinkedList.cpp
#include "LinkedList.h"
#include <iostream>
#include <stdlib.h>


LinkedList::LinkedList()
{
size = 0;
}

LinkedList::~LinkedList()
{
//dtor
}

void LinkedList::addAtFront(int newElement)
{
if (size == 0)
{
    Node temp;
    temp.data.id = newElement;
    temp.data.key = 0;
    head = &temp;
    tail = &temp;
    ++size;
}
else
{
    Node temp;
    temp.data.id = newElement;
    temp.data.key = size;
    temp.next = head;
    head->prev = &temp;
    head = &temp;
    ++size;
}
}

void LinkedList::addAtBack(int newElement)
{
if (size == 0)
{
    Node temp;
    temp.data.id = newElement;
    temp.data.key = 0;
    head = &temp;
    tail = &temp;
    ++size;
}
else
{
    Node temp;
    temp.data.id = newElement;
    temp.data.key = 0;
    tail->next = &temp;
    temp.prev = tail;
    tail = &temp;
    ++size;
}
}

LinkedListTest.cpp
#include "LinkedListTest.h"
#include "LinkedList.h"

int main()
{
LinkedList list = new LinkedList();
list.addAtFront(0);
}
4

5 に答える 5

5

new LinkedList()このエラーは、ポインターとして宣言されていLinkedList*ないLinkedList リストがどこかにあることを意味しますLinkedList。そのはず:

LinkedList* list = new LinkedList(); // I declare a pointer to a list
list->addAtFront(0); // I call a method on a pointer to an object

また

LinkedList list;
list.addAtFront(0);

これらは 2 つの異なるストレージに割り当てられる 2 つの異なるタイプであり、これは重要です。読み続けてください。

もっと重要なことは、動的に割り当てられたメモリを使用する場合、宣言されているスコープを保持する必要があるヒープ オブジェクトに実際に割り当てる必要があるということです。

より具体的には、これは:

{
  Node temp;
  ..
  head = &temp;
  ..
}

はスタック上の自動ストレージとして宣言されているため、これは問題を引き起こします。つまり、アドレスを取得してまたはその他tempに割り当てると、スコープが終了すると、そのアドレスは無効になります。ヒープに割り当てる必要があります。headtail

Node temp = new Node(value, id);
head = temp;
tail = temp;
++size;

Nodeこれには、不要になったときにヒープから自分でメモリをクリーンアップする必要があることに注意してください。

于 2013-10-21T00:33:53.910 に答える
1

2 つのクラスを実装する必要があると思います。

  1. センチネル付き二重連結リスト: Double_sentinel_list、および
  2. 二重にリンクされたノード: Double_node.

メンバー変数。コンストラクタ、デストラクタ:

int size() const; 
  //Returns the number of items in the list.
bool empty() const;  
  // Returns true if the list is empty, false otherwise.
Type front() const;  
  // Retrieves the object stored in the node pointed to by the next pointer of the head sentinel. This function throws a underflow if the list is empty. 
Type back() const;   
  // Retrieves the object stored in the node pointed to by the previous pointer of the tail sentinel. This function throws a underflow if the list is empty.
Double_node<Type> *head() const;  
  // Returns the head pointer.
Double_node<Type> *tail() const;  
  // Returns the tail pointer.
int count( Type const & ) const;  
  // Returns the number of nodes in the linked list storing a value equal to the argument. Mutators

このクラスには 7 つのミューテーターがあります。

void swap( Double_sentinel_list & );  
  // The swap function swaps all the member variables of this linked list with those of the argument.
Double_sentinel_list &operator=( Double_sentinel_list & );  
  // The assignment operator makes a copy of the argument and then swaps the member variables of this node doubly linked sentinel list those of the copy.
void push_front( Type const & );  
  // Creates a new Double_node<Type> storing the argument, the next pointer of which is set to the next pointer of the sentinel and the previous pointer is set to point to the sentinel. Theprevious pointer of what was the first node is set to the new node.
void push_back( Type const & );  
  //  Similar to push_front, this places a new node at the back of the list.
Type pop_front();  
  // Delete the first non-sentinel node at the front of the linked list and the previous and next pointers of any other node (including the sentinels) within the list. Return the object stored in the node being popped. Throw an underflow exception if the list is empty.
Type pop_back();  
  // Similar to pop_front, delete the last non-sentinel node in the list. This function throws a underflow if the list is empty.
int erase( Type const & );  
  // Delete the first node (from the front and other than the sentinals) in the linked list that contains the object equal to the argument (use == to to test for equality with the retrieved element). Update the previous and next pointers of any other node (including possibly the sentinels) within the list. Return the number of nodes that were deleted. 
于 2016-09-29T05:10:58.453 に答える
1

new は、ポインターではなく、LinkedList オブジェクトに割り当てようとしている LinkedList オブジェクトへのポインターを返します。

LinkedList list = new LinkedList();

読むべき

LinkedList list;
于 2013-10-21T00:30:36.383 に答える
0

また

LinkedList list;
list.addAtFront(0);

また

LinkedList* list = new LinkedList();
list->addAtFront(0);
delete list;
于 2013-10-21T00:30:53.713 に答える