1

所以,我正在尝试实现一个复制构造函数,在实例化一个对象时,我可以选择从头到尾(正常)或尾到头(反向)复制列表。现在,当我使用复制构造函数时,它总是从头到尾复制,即使它进入相反的条件。

这是我的头文件:

#include <iostream>
#include "Student.h"
#include "Node.h"
using namespace std;

class List {

public:
    List(); // Default constructor
    List(const List&); // Copy constructor (2-in-1, see lab sheet)
    ~List(); // Destructor

    bool isEmpty(); // List is empty: TRUE or FALSE?
    int getNumNodes() {return numNodes;} // How many Nodes in List

    void append(Student *); // Append new Node to head or tail of List
    void insert(Student *); // Inserts new Node in the
                            // Appropriate location in List
    void deleteNode(string); //Search for and delete specific Node
    void displayAscending();// Display List HEAD to TAIL
    void displayDescending(); // Display List TAIL to HEAD

    // input Student::data into Student pointer.
    void input(Student*, string, string, string, string, string);

    Node *getHead() const {return head;} // ptr to head. 
    Node *getTail() const {return tail;} //ptr to tail.

private:
    void printer(Node *); //recursive function w/in displayDescending()
    Node *head;
    Node *tail;

    bool empty;
    bool forward; // forward = head-to-tail i.e. true
    int numNodes; // number of nodes in the list 
};

这是我的复制构造函数。

List::List(List &list) { // Copy constructor
    head = NULL; // Head pointer set to NULL initially
    tail = NULL; // Tail pointer set to NULL initially

    empty = true;
    forward = true; // Copies head-to-tail by default.
    numNodes = 0;

    string flag; // Stores prompt value.
    cout << "Copy from head to tail? (y/n): ";
    cin >> flag; // prompt for user.
    if(flag == "n")
        forward = false;

    Node *curr = NULL; //initialize curr in function scope.

    if(flag == "n") {
        forward = false;
        curr = list.getTail(); // curr points to list tail.
        cout << "Copying in reverse order...\n" << endl;
    } else { // forward == true
        curr = list.getHead(); // curr points to list head.
        cout << "Copying from head-to-tail...\n" << endl;
    } // end if/else 

    while(curr) {
        string f = ( curr->getData()->getFirst()  );
        string m = ( curr->getData()->getMid()    );
        string l = ( curr->getData()->getLast()   );
        string s = ( curr->getData()->getSocial() );
        string a = ( curr->getData()->getAge()    );

        Node *nodePtr = NULL; // a node that's pointing 
                              // using it to point to creation of
                              // a new node
        Student *stuPtr = new Student; // creates a stud pointer on
                                       // heap of Student class in
                                       // order to store stud info 
        input(stuPtr,f,m,l,s,a); // input Student::data into stuPtr.      
        append(stuPtr); // append the node with stuPtr to head or tail
                        // of list.

        if(!forward)
            curr = curr->getPrev();
        else
            curr = curr->getNext();
    }  // end while*/
    cout << "Done copying!\n" << endl;
} // end copy constructor

此外,如果您需要查看它如何附加到列表,这里是 append() 函数。

void List::append(Student *newStudent) {
    Node *newNode = new Node(newStudent); // new Node containing student arg.

    newNode->getData(); // get data of student arg.

    if(isEmpty()) {  // tail=NULL, no list.
        cout << "List is empty. Inserting first Node.\n" << endl;
        head = newNode;
        tail = newNode; // new Node becomes head & tail.
    } else { 
        if(forward) { // append to tail of list.
            tail->setNext(newNode); // NEXT ptr of tail points to newNode.
            newNode->setPrev(tail); // newNode's PREV points to former tail.
            tail = newNode; // newNode becomes the new tail.
        } else { // append to head of list.
            head->setPrev(newNode); // PREV ptr of head points to newNode.
            newNode->setNext(head); // newNode's NEXT points to former head.
            head = newNode; // newNode becomes the new head.
        } // end if/else
    } // end if/else
    numNodes++;
}
4

2 回答 2

2

您似乎总是从头到尾复制的原因是您的代码不整洁,并且试图一次以不止一种方式做同样的事情。如果您尝试从尾部复制到头部,则将新列表从尾部写入头部,并将旧列表从尾部读取到头部。这两个相互抵消。想想看。

如果您尝试提出参数,则会出现编译器错误的原因是您使用andconst查询它,而您没有提出。getTail()getHead()const

编辑:

让我们回到设计并考虑一下尾对头复制应该如何工作。基本上有两种方法可以做到这一点,从头到尾读取和从头到尾写入:

|                |
v                v
A-B-C-D          A

  |            |
  v            v
A-B-C-D        B-A

    |        |
    v        v
A-B-C-D      C-B-A

      |    |
      v    v
A-B-C-D    D-C-B-A

反之亦然:

      |    |
      v    v
A-B-C-D    D

    |        |
    v        v
A-B-C-D    D-C

  |            |
  v            v
A-B-C-D    D-C-B

|                |
v                v
A-B-C-D    D-C-B-A

Bur 如果我们尝试两者都做,它们会取消:

      |          |
      v          v
A-B-C-D          D

    |          |
    v          v
A-B-C-D        C-D

  |          |
  v          v
A-B-C-D      B-C-D

|          |
v          v
A-B-C-D    A-B-C-D

我们所要做的就是选择一个。如果我们选择第一个,我们更改复制 ctor:

curr = list.getHead(); // curr points to list head.
cout << "Reading from head-to-tail...\n" << endl;

while(curr) {
  ...
  append(stuPtr); // append the node with stuPtr to head or tail of list.

  curr = curr->getNext();
}  // end while*/

它有效。如果我们选择第二个,我们不理会 ctor 并更改append(...)

if(isEmpty()) {  // tail=NULL, no list.
  cout << "List is empty. Inserting first Node.\n" << endl;
  head = newNode;
  tail = newNode; // new Node becomes head & tail.
} else {
  tail->setNext(newNode); // NEXT ptr of tail points to newNode.
  newNode->setPrev(tail); // newNode's PREV points to former tail.
  tail = newNode; // newNode becomes the new tail.
} // end if/else

一般来说,避免此类问题的方法是从小而简单开始,一次增加一点复杂性,每一步都测试,先隔离测试新功能,永远不要添加不起作用的代码。查找非明显错误的方法是获取您的代码并简化,逐步消除复杂性,直到您达到仍然表现出错误行为的最简单版本 - 或者更有可能该错误在此过程中变得明显。

于 2013-08-16T00:11:18.910 回答
1

By having a const argument, you're calling a non-const member function on const object. Non-const functions do not promise to not modify the object. You can declare these member functions as const to avoid this error:

Node *getHead() const

.. and so on

As for your first question, I don't know how to solve it (yet), I have a few recommendations:

  • Use nullptr instead of NULL or 0
  • Use list initialisation for your strings: string f { curr->getData()->getFirst() };

I suggest you debug your code line by line, using a good debugger tool, like Visual Studio; it will help you solve your problem in minutes. If you are still unsure, you can cut the amount of code to be tested, down to a few lines and post it.

于 2013-08-16T00:06:52.163 回答