В программе есть указатель на объект класса WordList *TheList;
, WordList имеет подклассы WordDataList и WordDataDLinkList, поэтому в случае case мы интерпретируем, какой подкласс использовать и как распечатать информацию в списке. Из того, что я понимаю в спецификациях, каждый случай должен объявлять TheList как указатель этого типа и использовать его, а затем восстановить память в конце case, чтобы ее можно было использовать в следующей итерации цикла. Когда я пытаюсь что-то вроде:
while (true)
{
displayMenu();
cin>>selection;
switch(selection)
{
case '1':
TheList = new WordDataList;
TheList->parseIntoList(inf);
TheList->printIteratively();
delete TheList;
break;
case '2':
TheList = new WordDataList;
TheList->parseIntoList(inf);
TheList->printRecursively();
delete TheList;
break;
case '3':
TheList = new WordDataList;
TheList->parseIntoList(inf);
TheList->printPtrRecursively();
delete TheList;
break;
case '6':
cout<<"Goodbye"<<endl;
return 0;
default:
cout<<"I cannot understand "<<selection<<". Try again."<<endl;
break;
} // switch
} // while
Удаление указателя делает так, что после первого прогона не отображаются данные (меню все еще появляется), а опция 2 заканчивается сбоем. Я изменяю код, который дал мой профессор, и когда у него не было вызова на удаление, а новый WordDataList и parseIntoList перед циклом он работал нормально. Какие-либо предложения?
Добавлено:
Я инициализирую TheList в каждом случае, потому что буду добавлять 4 и 5, которые будут использовать WordDataDLinkList. Если это указатель на WordDataList извне оператора case, как мне изменить его на WordDataDLinkList внутри, когда мне нужно? Мой профессор написал WordDataList для нас:
#include <sstream>
#include <iostream>
#include "WordDataList.h"
using namespace std;
WordDataList::WordDataList()
{ numWords=0; }
bool WordDataList::incMatch(string temp)
{ for(int i=0; i<numWords; i++) {
if (temp==TheWords[i].getWord()) {
TheWords[i].incCount();
return true;
}
}
return false;
}
void WordDataList::parseIntoList(ifstream &inf)
{ string temp;
while (inf >> temp)
if (!incMatch(temp) && numWords < 10) {
TheWords[numWords].setWord(temp);
TheWords[numWords++].setCount(1);
}
}
// Print the data iteratively
void WordDataList::printIteratively()
// void printObjectArrayIterator(WordData TheWords[], int numWords)
{
cout<<"--------------------------"<<endl;
cout<<"|Object Array Iterative|"<<endl;
cout<<"|Word Occurences |"<<endl;
cout<<"--------------------------"<<endl;
for(int i=0; i<numWords; i++)
cout<<" "<<TheWords[i]<<endl;
}
// Print the data recursively
void WordDataList::printRecursivelyWorker(int numWords)
//void printObjectArrayRecursive(WordData TheWords[], int numWords)
{if (numWords==1) {
cout<<"--------------------------"<<endl;
cout<<"|Object Array Recursive|"<<endl;
cout<<"|Word Occurences |"<<endl;
cout<<"--------------------------"<<endl;
cout<<" "<<TheWords[numWords-1]<<endl;
return;
}
printRecursivelyWorker(numWords-1);
cout<<" "<<TheWords[numWords-1]<<endl;
}
// Call worker function to print the data recursively
void WordDataList::printRecursively()
{ printRecursivelyWorker(numWords); }
// Print the data recursively with a pointer
void WordDataList::printPtrRecursivelyWorker(int numWords)
//void printObjectArrayPointerRecursive(WordData* TheWords, int numWords)
{if (!numWords)
{ cout<<"--------------------------"<<endl;
cout<<"|Object Array Pointer |"<<endl;
cout<<"|Word Occurences |"<<endl;
cout<<"--------------------------"<<endl;
return;
}
printPtrRecursivelyWorker(numWords-1);
cout<<" "<<*(TheWords+(numWords-1))<<endl;
}
// Call worker function to print the data recursively
void WordDataList::printPtrRecursively()
{ printPtrRecursivelyWorker(numWords); }
Я думаю, вы запутались в чем-то другом. Почему вам нужно воссоздать "WordDataList" - это методы анализа и печати, модифицирующие его?
Если нет, просто создайте его один раз и просто используйте кнопку выбора, чтобы выбрать, какую функцию печати использовать, если она есть.
Я также предложил бы поместить каждый набор инструкций для выполнения случая в закрытие и добавить некоторые распечатки или пройти через отладчик, чтобы посмотреть, что происходит. Основные догадки в том, что ваш "новый" возвращает NULL таким образом, что вы не можете вызвать его членов правильно или деструктор плох.
Итак, из того, что я могу сказать: Опции 1-3 должны выбрать другой подкласс для вашего указателя TheList
. TheList
- это указатель на ваш базовый класс, чтобы это было хорошо. Я думаю, что вам нужно сделать new
соответствующий подкласс в каждом операторе switch. IE
case '1': TheList = new WordDataDLinkList();
EDIT: если вы намереваетесь вызывать другую версию каждой функции-члена, основанной на том, что вы используете в настоящий момент, как в WordDataDLinkList::parseIntoList(inf)
, вместо WordDataList::parseIntoList(inf)
, попробуйте прочитать полиморфизм