以下是参考代码:
#include <iostream>
using namespace std;
class linkedList {
struct listNode{ //a node of a list
int value;
struct listNode *next;
};
listNode *head;
public:
linkedList(){
cout << "hello1n";
head = NULL;
};
linkedList(listNode* a){
cout << "hello2n";
head = a;
};
~linkedList();
listNode* getHead() {return head;}
void appendNode(int);
//inline Search function due to unable to function outside of class definition
listNode* rangeSearch(int a, int b){
//listNode to search
listNode *search = head;
//listNode* toReturn = new listNode;
//listNode to return list of values that are found within range
linkedList *found = new linkedList;
while(search){
//if the current value is within range, then add to list
if(search->value >= a && search->value <= b){
//append searched value onto found
found->appendNode(search->value);
//after appending, go to next value
}
search = search->next;
}
return found->getHead();
}
void display();
};
int main()
{
cout << "Programmer : nn";
cout << "Description : n";
linkedList* list = new linkedList;
int x = 12;
//values to search
int s1 = 10, s2 = 14;
// adds 2 to each number on list for 5 times
for(int i = 0; i < 5; i++){
list->appendNode(x);
x += 2;
}
//create something to hold pointer of found to be deleted when done using
//print list
cout << "Original set of numbers in linked list: ";
list->display();
cout << "nThe following are the values withing ranges: " << s1 << " and " << s2 << ":n";
//EDITED:
//list->rangeSearch(s1,s2);
linkedList foundList(list->rangeSearch(s1,s2));
foundList.display();
//End of edit 6:40PM 7/18/13
cout << "nHere are the original set of numbers in linked list (again): ";
list->display();
delete list;
return 0;
}
void linkedList::appendNode(int newValue)
{
listNode *newNode = new listNode(); // To point to a new node
listNode *nodePtr; // To move through the list
// Allocate a new node and store newValue there.
newNode->value = newValue;
newNode->next = 0;
// If there are no nodes in the list
// make newNode the first node.
if (!head)
head = newNode;
else // Otherwise, insert newNode at end.
{
// Initialize nodePtr to head of list.
nodePtr = head;
// Find the last node in the list.
while (nodePtr->next)
nodePtr = nodePtr->next;
// Insert newNode as the last node.
nodePtr->next = newNode;
}
}
void linkedList::display() {
for(listNode* p = head; p != NULL; p = p->next)
cout << p->value << ' ';
}
linkedList::~linkedList()
{
cout << "ndestructor called";
listNode *nodePtr; // To traverse the list
listNode *nextNode; // To point to the next node
// Position nodePtr at the head of the list.
nodePtr = head;
// While nodePtr is not at the end of the list...
while (nodePtr != NULL)
{
// Save a pointer to the next node.
nextNode = nodePtr->next;
// Delete the current node.
delete nodePtr;
// Position nodePtr at the next node.
nodePtr = nextNode;
}
}
这里有几个问题。首先,为什么当我试图将rangeSearch成员函数放在类定义之外时,编译器会给出一个错误,说listNode*类型无法识别?
其次,这与析构函数有关。在这个程序中,创建了2个实例(list&found list),但只调用了1个析构函数。有人能解释一下原因吗?我的直觉告诉我,指向linkedList对象的动态分配指针没有被破坏。然而,我不知道为什么。我之所以必须使用动态分配的内存,主要是因为我想将指针传递回主函数。如果我不这样做,当rangeSearch退出时,指针将被传递回main,但指针的任何列表都将在之后被解构返回ptr;(假设ptr是指向rangeSearch中声明的linkedList的指针)这将导致我的程序崩溃,因为现在地址中什么都没有,我正试图调用。。。没有什么
和往常一样,我会感谢任何一个伟大的撒玛利亚人,他愿意教育我更多这方面的知识。
首先,您在作用域方面遇到了问题。在C++中,大括号定义了一个新的作用域,因此您在类linkedlist中定义了listNode。如果你想访问它,你必须使用作用域操作符,比如linkedlist::listNode
我不完全理解你的第二个问题。我只看到一个要删除的调用,那么为什么你认为会调用两个析构函数呢?只有当您调用delete时才会调用析构函数,所以除非您指定要销毁它,否则它仍然存在。
虽然我不完全理解你的问题,但我看到你在rangeSearch中返回了一个指向头部的指针,但你没有将其分配给任何东西。这意味着您将发生内存泄漏;你为找到的分配了内存,但没有对它做任何事情。事实上,由于你只返回头,如果你给它分配了一些东西,你仍然无法删除它,因为你无法访问链表本身。
linkNode嵌套在linkedList内部。将listNode移到linkedList类之外,就不会得到第一个错误。或者您可以使用它的完整声明linkedList::listNode。此外,如果将linkNode嵌套,则必须将其公开。
总的来说,你可以说
linkedList list;
而不是
linkedList* list = new linkedList;
rangeSearch()正在返回一个值,但该值从未分配给main()中的任何内容。rangeSearch()正在分配一个linkedList,但它从未被删除。