undefined reference error: `ClassName:: ClassMember` - c++

Why my program is getting these errors?
undefined reference to `PizzaOrder::toppings_offered'
undefined reference to `PizzaOrder::arraySize'
undefined reference to `PizzaOrder::base_price'
undefined reference to `PizzaOrder::MedPizBase'
undefined reference to `PizzaOrder::base_price'
undefined reference to `PizzaOrder::LargePizBase'
...
This is my program:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class PizzaOrder
{
private:
int size;
int num_toppings;
string toppings[100];
public:
static const string toppings_offered[];
static const double topping_base_cost;
static const double base_price;
static const string defaultSize;
static const double MedPizBase;
static const double LargePizBase;
static const int arraySize;
PizzaOrder();
PizzaOrder(int size);
// MUTATORS & ACCESSORS & METHODS
int GetSize() { return size; }
int GetNumToppings() { return num_toppings; }
string GetToppings();
void GetPrice();
bool SetSize(int size);
void AddTopping(string topping);
void AddTopping(int n); //int represents position in array toppings_offered[]
string StringizeSize(int size);
void DisplayPizza();
};
const string toppings_offered[] = {"1. Onions", "2. Bell Peppers",
"3. Olives", "4. Pepperoni", "5. Sausage",
"6. Mushrooms", "7. Jalapenos"};
const string defaultSize = "Small ";
const double topping_base_cost = 1;
const double base_price = 7;
const double MedPizBase = 0.15;
const double LargePizBase = 0.25;
const int arraySize = sizeof(toppings_offered)/sizeof(toppings_offered[0]);
PizzaOrder::PizzaOrder()
{
SetSize(0);
}
PizzaOrder::PizzaOrder(int size)
{
if (!SetSize(size))
SetSize(0);
}
string PizzaOrder::StringizeSize(int size)
{
string pizzaSize;
if (size == 0)
pizzaSize = "Small";
if (size == 1)
pizzaSize = "Medium";
if (size == 2)
pizzaSize = "Large";
return pizzaSize;
}
bool PizzaOrder::SetSize(int size)
{
if (size != 0 && size != 1
&& size != 2)
return false;
this->size = size;
return true;
}
void PizzaOrder::AddTopping(string topping) // totally wrong
{
for (int i = 0; i < arraySize; i++)
{
if (topping == toppings_offered[i])
{
toppings[num_toppings] = topping;
num_toppings++;
}
}
}
void PizzaOrder::AddTopping(int n) //increments n by 1 for each valid topping chosen
{
if (n > 0 && n < 7)
n++;
n = num_toppings;
}
string PizzaOrder::GetToppings()
{
string result;
for(int i = 0; i < GetNumToppings(); i++)
{
result += toppings[i];
}
return result;
}
void PizzaOrder::DisplayPizza()
{
cout << "Your pizza order: " << PizzaOrder::StringizeSize(GetSize()) << ", "
<< PizzaOrder::GetNumToppings() << ", "
<< PizzaOrder::GetToppings();
}
void PizzaOrder::GetPrice()
{
double TotalPizPrice;
double MedPizzaPrice = base_price+(base_price*MedPizBase);
double LargePizzaPrice = base_price+(base_price*LargePizBase);
double topPrice = (GetNumToppings()*topping_base_cost);
if (GetSize() == 0)
TotalPizPrice = topPrice+base_price;
if (GetSize() == 1)
TotalPizPrice = topPrice+MedPizzaPrice;
if (GetSize() == 2)
TotalPizPrice = topPrice+LargePizzaPrice;
cout << "Your pizza's total price is: $" << TotalPizPrice;
}
int main()
{
PizzaOrder pizza;
string choice;
char selection;
int topChoice;
do
{
cout << "Size of pizza (Small, Medium, Large) or Quit?\n" << endl;
getline(cin, choice);
selection = choice[0];
if (selection == 'S' || selection == 's')
pizza.SetSize(0);
if (selection == 'M' || selection == 'm')
pizza.SetSize(1);
if (selection == 'L' || selection == 'l')
pizza.SetSize(2);
do
{
cout << "Current pizza: "
<< pizza.StringizeSize(pizza.GetSize())
<< pizza.GetToppings() << "\n"
<< "Select an item by number (0 when done):\n" << endl;
for (int i = 0; i < 8; i++)
{
cout << toppings_offered[i] << "\n";
}
cout <<"\nSelection: ";
cin >> topChoice;
pizza.AddTopping(topChoice);
}
while (topChoice != 0);
}
while(selection != 'q' && selection != 'Q');
pizza.DisplayPizza();
pizza.GetPrice();
return 0;
}

The definition of static member variables is wrong, they should be:
const string PizzaOrder::defaultSize = "Small ";
~~~~~~~~~~~~
...
Otherwize they'll be just global variables.

Related

Writing a priority queue with a max heap structure in c++

I am writing a priority queue with a max heap structure as an assignment for school. I can either write it as an array or I can use a vector. I chose a vector. So the assignment is this, the user chooses options from a menu where he either wants to add,print, or view the elements. When the user chooses to add he gets ask who wants to be added, the instructor, student, or TA. He can enter i,I,t,T,S,s. The instructor having the highest priority where if the user chooses the option to print and there is an instructor in the queue he gets to go first. The TA having the second highest priority where if there is a TA and a student in the queue, the TA goes first. If there is is more than one instructor than the queue acts as a normal queue. I have written most of it, or tried. I got my max heap implementation from my textbook since they provide one. Now the problem is this, when I have more than one item in the priority queue and I choose to print, it crashes and gives me a vector subscript out of range exception. I been trying to fix it and no luck. Also, when I try to print the elements in the queue or print them, it needs to say the job# with the name of the person. Can someone help me find a way to implement that.
#pragma once
#include <vector>
struct Heap
{
std::vector<int> m_elements;
void ReHeapDown(int, int);
void ReHeapUp(int, int);
void Swap(int& a, int& b);
};
#include "heap.h"
void Heap::ReHeapDown(int index, int bottom)
{
int maxChild, rightChild, leftChild;
leftChild = index * 2 + 1;
rightChild = index * 2 + 2;
if (leftChild <= bottom)
{
if (leftChild == bottom)
maxChild = leftChild;
else
{
if (m_elements[leftChild] <= m_elements[rightChild])
maxChild = rightChild;
else
maxChild = leftChild;
}
if (m_elements[index] < m_elements[maxChild])
{
Swap(m_elements[index], m_elements[maxChild]);
ReHeapDown(maxChild, bottom);
}
}
}
void Heap::ReHeapUp(int index, int bottom)
{
int parent;
if (bottom > index)
{
parent = (bottom - 1) / 2;
if (m_elements[parent] < m_elements[bottom])
{
Swap(m_elements[parent], m_elements[bottom]);
ReHeapUp(index, parent);
}
}
}
void Heap::Swap(int& a, int& b)
{
int temp;
temp = a;
a = b;
b = temp;
}
#include <iostream>
#include "heap.h"
#pragma once
class PQTYPE
{
private:
Heap m_Items;
public:
bool isEmpty() const;
void Enqueue(int, std::string);
void Dequeue(int, std::string);
void printElements();
};
#include "pqtype.h"
bool PQTYPE::isEmpty() const
{
return m_Items.m_elements.empty();
}
void PQTYPE::Enqueue(int newItem, std::string lName)
{
if (lName == "Student")
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
else if (lName == "TA")
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
else if (lName == "Instructor")
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
}
void PQTYPE::Dequeue(int item, std::string lName)
{
if (isEmpty())
std::cout << "No jobs to print\n";
else
{
m_Items.m_elements[0] = m_Items.m_elements.back();
std::cout << "Now printing Job#" << m_Items.m_elements[item - 1] << " " << lName.c_str() << std::endl;
m_Items.m_elements.pop_back();
m_Items.ReHeapDown(0, item - 1);
}
}
void PQTYPE::printElements()
{
if (isEmpty())
std::cout << "No jobs to print\n";
else
{
for (int i = 0; i < m_Items.m_elements.size(); i++)
{
std::cout << "Job#" << m_Items.m_elements[i] << std::endl;
}
}
}
#include"pqtype.h"
struct Person
{
int m_priority;
std::string m_name;
Person()
{
m_priority = 0;
m_name = " ";
}
};
int showMenu();
void addJobs(PQTYPE&, Person&);
void printJobs(PQTYPE&, Person&);
void viewJobs(PQTYPE&);
int main()
{
int option;
Person p;
PQTYPE pq;
do
{
option = showMenu();
switch (option)
{
case 1: addJobs(pq, p);
break;
case 2: printJobs(pq, p);
break;
case 3: viewJobs(pq);
break;
case 4:
break;
default: std::cout << "Wrong input\n";
break;
}
} while (option != 4);
return 0;
}
int showMenu()
{
int choice;
std::cout << " 1.)Add Job\n";
std::cout << " 2.)Print Job\n";
std::cout << " 3.)View Jobs\n";
std::cout << " 4.)Exit\n";
std::cout << " Enter Choice: ";
std::cin >> choice;
return choice;
}
void addJobs(PQTYPE& pq, Person& per)
{
char jobChoice;
std::cout << "Who is the job for ( Instructor(i or I), TA(t or T), Student(s or S) :";
std::cin >> jobChoice;
if (jobChoice == 'S' || jobChoice == 's')
{
per.m_priority++;
per.m_name = "Student";
pq.Enqueue(per.m_priority, per.m_name);
}
else if (jobChoice == 'T' || jobChoice == 't')
{
per.m_priority++;
per.m_name = "TA";
pq.Enqueue(per.m_priority, per.m_name);
}
if (jobChoice == 'I' || jobChoice == 'i')
{
per.m_priority++;
per.m_name = "Instructor";
pq.Enqueue(per.m_priority, per.m_name);
}
}
void printJobs(PQTYPE& pq, Person& p)
{
pq.Dequeue(p.m_priority, p.m_name);
}
void viewJobs(PQTYPE& pq)
{
pq.printElements();
}
In your original code the index used inside Dequeue() for accessing the vector doesn't seem to be initialised in the right way. Let's assume that you have added two entries to your list. In this case the value of P.m_priority inside your main() is 2. Now you're calling printJobs() for the first time. printJobs() calls pq.Dequeue(p.m_priority, p.m_name), so Dequeue() gets p.m_priority as its parameter item. Keep in mind that item has the value 2.
m_Items.m_elements[0] = m_Items.m_elements.back();
std::cout << "Now printing Job#" << m_Items.m_elements[item - 1] << " " << lName.c_str() << std::endl;
m_Items.m_elements.pop_back();
You're accessing your std::vector using an index of item - 1. This works for the first time, as there are two elements in your list. In this call, there is also a pop_back() done on your list, which decreases its size by one. The next time you call printJobs(), the given parameter item won't have changed, it still has the value 2. When you access your Itemlist, there is no longer an index of 1, and an subscript out of range exception will be thrown.
There were no fixed priorities assigned to the three entry types in your original version, so I added these (see addJobs() ).
So a possible solution to store the person's name could look like this:
struct Person
{
int m_priority;
std::string m_name;
Person()
{
m_priority = 0;
m_name = " ";
}
};
struct Heap
{
std::vector<Person> m_elements;
void ReHeapDown(int, int);
void ReHeapUp(int, int);
void Swap(Person& a, Person& b);
};
void Heap::ReHeapDown(int index, int bottom)
{
int maxChild, rightChild, leftChild;
leftChild = index * 2 + 1;
rightChild = index * 2 + 2;
if (leftChild <= bottom)
{
if (leftChild == bottom)
maxChild = leftChild;
else
{
if (m_elements[leftChild].m_priority <= m_elements[rightChild].m_priority)
maxChild = rightChild;
else
maxChild = leftChild;
}
if (m_elements[index].m_priority < m_elements[maxChild].m_priority)
{
Swap(m_elements[index], m_elements[maxChild]);
ReHeapDown(maxChild, bottom);
}
}
}
void Heap::ReHeapUp(int index, int bottom)
{
int parent;
if (bottom > index)
{
parent = (bottom - 1) / 2;
if (m_elements[parent].m_priority < m_elements[bottom].m_priority)
{
Swap(m_elements[parent], m_elements[bottom]);
ReHeapUp(index, parent);
}
}
}
void Heap::Swap(Person& a, Person& b)
{
Person temp;
temp = a;
a = b;
b = temp;
}
#include <iostream>
class PQTYPE
{
private:
Heap m_Items;
public:
bool isEmpty() const;
void Enqueue(Person);
void Dequeue();
void printElements();
};
bool PQTYPE::isEmpty() const
{
return m_Items.m_elements.empty();
}
void PQTYPE::Enqueue(Person newItem)
{
if (!newItem.m_name.compare("Student"))
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
else if (!newItem.m_name.compare("TA"))
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
else if (!newItem.m_name.compare("Instructor"))
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
}
void PQTYPE::Dequeue()
{
if (isEmpty())
std::cout << "No jobs to print\n";
else
{
Person front = m_Items.m_elements.front();
std::cout << "Now printing Job#" << front.m_priority << " " << front.m_name.c_str() << std::endl;
m_Items.m_elements.erase(m_Items.m_elements.begin());
m_Items.ReHeapDown(0, m_Items.m_elements.size() - 1);
}
}
void PQTYPE::printElements()
{
if (isEmpty())
std::cout << "No jobs to print\n";
else
{
for (int i = 0; i < m_Items.m_elements.size(); i++)
{
std::cout << "Job#" << m_Items.m_elements[i].m_priority << " " << m_Items.m_elements[i].m_name.c_str() << std::endl;
}
}
}
int showMenu();
void addJobs(PQTYPE&, Person&);
void printJobs(PQTYPE&, Person&);
void viewJobs(PQTYPE&);
int showMenu()
{
int choice;
std::cout << " 1.)Add Job\n";
std::cout << " 2.)Print Job\n";
std::cout << " 3.)View Jobs\n";
std::cout << " 4.)Exit\n";
std::cout << " Enter Choice: ";
std::cin >> choice;
return choice;
}
void addJobs(PQTYPE& pq, Person& per)
{
char jobChoice;
std::cout << "Who is the job for ( Instructor(i or I), TA(t or T), Student(s or S) :";
std::cin >> jobChoice;
if (jobChoice == 'S' || jobChoice == 's')
{
per.m_priority = 0;
per.m_name = "Student";
pq.Enqueue(per);
}
else if (jobChoice == 'T' || jobChoice == 't')
{
per.m_priority = 1;
per.m_name = "TA";
pq.Enqueue(per);
}
if (jobChoice == 'I' || jobChoice == 'i')
{
per.m_priority = 2;
per.m_name = "Instructor";
pq.Enqueue(per);
}
}
void printJobs(PQTYPE& pq)
{
pq.Dequeue();
}
void viewJobs(PQTYPE& pq)
{
pq.printElements();
}
int main()
int option;
Person p;
PQTYPE pq;
do
{
option = showMenu();
switch (option)
{
case 1: addJobs(pq, p);
break;
case 2: printJobs(pq);
break;
case 3: viewJobs(pq);
break;
case 4:
break;
default: std::cout << "Wrong input\n";
break;
}
} while (option != 4);
return 0
}
Are you sure that the methods ReHeapUp and ReHeapDown meet your requirements? And shouldn't there be a distinction between job number and priority?

My program prints random cards, but it will not recognize when there is a repeat card

I am a beginner with C++ and have tried a few different things, but no matter what I try it doesn’t seem to recognize when a card has already been drawn...
I have tried to utilize to bool isDrawn, but after a few attempts of that with no success I am not 100% sure where to go from here
class Card {
public:
string suitName;
int cardNumber;
void printCard() {
if (cardNumber == 1) {
cout << "Ace";
} else if (cardNumber == 11) {
cout << "Jack";
} else if (cardNumber == 12) {
cout << "Queen";
} else if (cardNumber == 13) {
cout << "King";
} else
cout << cardNumber;
cout << " of " << suitName << endl;
}
bool isDrawn = false;
};
class Deck {
public:
Card deck[52];
void makeDeck(){
int counter = 0;
string suits[] = { "Spades", "Hearts", "Clubs", "Diamonds" };
string face[] = { "Ace", "Jack", "Queen", "King" };
for (int i = 0; i <= 3; i++) {
for (int j = 0; j < 13; j++) {
deck[counter].isDrawn = false;
deck[counter].cardNumber = (j + 1);
deck[counter].suitName = suits[i];
counter++;
}
}
}
Card drawCard() {
int randcard;
do {
randcard = rand() % 52;
} while (deck[randcard].isDrawn == true);
return deck[randcard];
}
};
class Player {
public:
vector<Card> hand;
void setName(string s){
name = s;
}
string printName(){
return name;
}
void printHand() {
for (int i = 0; i < hand.size(); i++){
hand.at(i).printCard();}
}
private:
string name;
};
int main() {
Deck my_deck;
Player p1;
p1.setName("HAL 9000");
cout << p1.printName() << endl;
my_deck.makeDeck();
p1.hand.push_back(my_deck.drawCard());
p1.hand.push_back(my_deck.drawCard());
p1.hand.push_back(my_deck.drawCard());
p1.printHand();
cout << endl;
}

C++ none of the 3 overloads could convert all the argument types line 39 1

So after coding this I got an error : C++ none of the 3 overloads could convert all the argument types line 39 1 in w5.cpp
do you know where is the problem? and could you help me to fix it? I actually dont know why it is showing this because I got the default constructor for this code.
//w5.h
#define MAX_LINE_LENGTH 256
#define MAX_PURCHASES 5
// w5.cpp
#include <iostream>
#include <cstring>
#include "w5.h"
#include "CreditStatement.h"
using namespace std;
void sort(CreditStatement* statement, int n);
int main()
{
double price;
int n = 0;
CreditStatement statement[MAX_PURCHASES];
cout << "Credit Statement Processor\n";
cout << "==========================\n";
do
{
cout << "Item price (0 to quit): ";
cin >> price;
if (cin.fail() || (cin.get() != '\n'))
{
cin.ignore(2000, '\n');
cerr << "Bad character. Try again." << endl;
cin.clear();
}
else if ((int)price != 0)
{
cout << "Statement item: ";
char item[MAX_LINE_LENGTH];
cin.getline(item, MAX_LINE_LENGTH);
if (strlen(item) > 0)
{
statement[n] = CreditStatement(item, price);
n++;
}
}
} while ((int)price != 0 && n < MAX_PURCHASES);
cout << endl;
sort(statement, n);
cout << " Credit Statement\n\n";
cout << " Item Price\n";
cout << "----------------------------------\n";
for (int i = 0; i < n; i++)
{
statement[i].display();
}
cout << endl;
return 0;
}
// sort sorts the elements of Credit Card Statement[n] in ascending order
//
void sort(CreditStatement* s, int n)
{
int i, j;
CreditStatement temp;
for (i = n - 1; i > 0; i--)
{
for (j = 0; j < i; j++)
{
if (s[j].isGreaterThan(s[j + 1]))
{
temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
}
//CreditStatement.h
class CreditStatement{
bool _valid;
double* _price;
char* _item;
public:
CreditStatement();
CreditStatement(char*, double*);
CreditStatement(const CreditStatement&);
CreditStatement& operator=(const CreditStatement&);
//output
void display() const;
//mutators
bool isGreaterThan(const CreditStatement&) const;
};
//CreditStatement.cpp
#include <iostream>
#include <new>
#include "CreditStatement.h"
using namespace std;
void CreditStatement::display() const{
cout << " Something" << _price << _item;
}
bool CreditStatement::isGreaterThan(const CreditStatement&) const{
return _valid;
}
CreditStatement::CreditStatement(){
_item = NULL;
_price = NULL;
}
CreditStatement::CreditStatement(char* iP, double* pP){
_price = NULL;
_item = NULL;
if (pP != NULL){
int sizepP = sizeof(pP) / sizeof(pP[0]);
_price = new (nothrow) double[sizepP];
if (_price){
for (int i = 0; i <sizepP; i++){
_price[i] = pP[i];
};
}
if (iP != NULL){
int sizeiP = sizeof(iP) / sizeof(iP[0]);
_item = new (nothrow) char [sizeiP];
if (_item){
for (int i = 0; i < sizeiP; i++){
_item[i] = iP[i];
};
}
}
}
}
CreditStatement::CreditStatement(const CreditStatement& otherCS){
*this = CreditStatement(otherCS._item, otherCS._price);
}
CreditStatement& CreditStatement::operator=(const CreditStatement& otherCS){
if (this != &otherCS)
{
if (_item){
delete[] _item;
_item = NULL;
}
if (_price){
delete[] _price;
_price = NULL;
}
else{
if (otherCS._price != NULL){
int sizepP = sizeof(otherCS._price) / sizeof(otherCS._price[0]);
_price = new (nothrow) double[sizepP];
if (_price){
for (int i = 0; i < sizepP; i++){
_price[i] = otherCS._price[i];
};
}
if (otherCS._item != NULL){
int sizeiP = sizeof(otherCS._item) / sizeof(otherCS._item[0]);
_item = new (nothrow) char[sizeiP];
if (_item){
for (int i = 0; i < sizeiP; i++){
_item[i] = otherCS._item[i];
};
}
}
}
}
}
return *this;
}
I also got this error
"no instance of constructor "CreditStatement::CreditStatement" matches the argument list
argument types are: (char [256], double) c:*\Project1\w5.cpp 38 20.
I think the problem is your call statement[n] = CreditStatement(item, price);
Here, price is a double, but there's a constructor CreditStatement(char*, double*); but none with signature CreditStatement(char*, double);
You might want to fix that.

Why is my data member empty even after construction?

I have included both my definition of the Question class and its implementation, the first is a header file and the second a cpp file.
I put comments in to show where the problem is. For some reason under the constructor I can cout the questionText just fine but when I try to do this under the getQuestionText function it just outputs an empty string? Any help would be most appreciated!! Thanks!
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#ifndef QUESTION_H
#define QUESTION_H
class Question{
public:
Question(int thePointValue, int theChapterNumber, \
string theQuestionText);
int getPointValue() const;
int getChapterNumber() const;
string getQuestionText() const;
virtual void writeQuestion(ostream& outfile) const;
virtual void writeKey(ostream& outfile) const;
private:
int pointValue;
int chapterNumber;
string questionText;
void writePointValue(ostream& outfile) const;
};
#endif
#include "Question.h"
Question::Question(int thePointValue, int theChapterNumber, \
string theQuestionText)
{
pointValue = thePointValue;
chapterNumber = theChapterNumber;
questionText = theQuestionText;
//HERE THIS WORKS PERFECTLY
cout << questionText << endl;
}
int Question::getPointValue() const
{
return pointValue;
}
int Question::getChapterNumber() const
{
return chapterNumber;
}
string Question::getQuestionText() const
{
//THIS IS THE PROBLEM. HERE IT OUPUTS AN EMPTY STRING NO MATTER WHAT!
cout << questionText << endl;
return questionText;
}
void Question::writeQuestion(ostream& outfile) const
{
writePointValue(outfile);
outfile << questionText << endl;
}
void Question::writeKey(ostream& outfile) const
{
writePointValue(outfile);
outfile << endl;
}
void Question::writePointValue(ostream& outfile) const
{
string pt_noun;
if (pointValue == 1)
pt_noun = "point";
else
pt_noun = "points";
outfile << "(" << pointValue << " " << pt_noun << ") ";
}
vector<Question *> QuestionsList(string filename, int min, int max)
{
vector<Question *> QuestionList;
string line;
vector<string> text;
ifstream in_file;
in_file.open(filename.c_str());
while (getline(in_file, line))
{
text.push_back(line);
}
string type;
for(int i = 0; i < text.size(); i ++)
{
int num = text[i].find('#');
type = text[i].substr(0, num);
if (type == "multiple")
{
MultipleChoiceQuestion myq = matchup(text[i]);
MultipleChoiceQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "short")
{
ShortAnswerQuestion myq = SAmatchup(text[i]);
ShortAnswerQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "long")
{
LongAnswerQuestion myq = LAmatchup(text[i]);
LongAnswerQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "code")
{
CodeQuestion myq = CODEmatchup(text[i]);
CodeQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
cout << QuestionList[QuestionList.size()-1]->getQuestionText() << endl;
}
for (int i = 0; i < QuestionList.size(); i ++)
{
int numm = QuestionList.size();
cout << QuestionList[numm-1]->getQuestionText() << endl;
}
return QuestionList;
}
then when i call this in main the code breaks
vector<Question *> list = QuestionsList(pool_filename, min_chapter, max_chapter);
cout << list[0]->getQuestionText() << endl;
You are declaring, multiple times in your code, local objects and storing their pointer into the QuestionList vector (returned by the function) which, at the end of the function block, will contains dangling pointers.
MultipleChoiceQuestion myq = matchup(text[i]); // < local object
MultipleChoiceQuestion* myptr = &myq; // < pointer to local object
QuestionList.push_back(myptr); // < push back into vector
At this point you can either use dynamic memory allocation (I suggest you not to do that unless you are absolutely forced, and even in that case use one of the smart pointers provided by the standard library) or store the objects directly inside the vector.

Trouble with Array Lists And Using the Insert and Retrieve Functions Given (Segment Core Dump)

I am having difficuly implementing a few functions in my array list.
I want to use the predefined function "insert" to insert a value into the list. I then want to use the retrieve function to print out the values of the entire list.
However, when I test my function, the program exits with a segmentation core dump after the last value is inserted
Any help would be appreciated.
Header:
/** #file ListA.h */
#include <string>
using namespace std;
const int MAX_LIST = 0;
typedef string ListItemType;
class List
{
public:
List();
bool isEmpty() const;
int getLength() const;
void insert(int index, const ListItemType& newItem, bool& success);
void retrieve(int index, ListItemType& dataItem, bool & success) const;
void remove(int index, bool& success);
List selectionSort(List selectList);
private:
ListItemType items[];
int size;
int translate(int index) const;
};
Implementation:
/** #file ListA.cpp */
#include "ArrayList.h" // header file
#include <iostream>
#include <fstream>
List::List() : size()
{
}
bool List::isEmpty() const
{
return size == 0;
}
int List::getLength() const
{
return size;
}
void List::insert(int index, const ListItemType& newItem, bool& success)
{
success = (index >= 1) &&
(index <= size + 1) &&
(size < MAX_LIST);
if (success)
{
for (int pos = size; pos >= index; --pos)
items[translate(pos + 1)] = items[translate(pos)];
items[translate(index)] = newItem;
++size;
}
}
void List::remove(int index, bool& success)
{
success = (index >= 1) && (index <= size);
if (success)
{
for (int fromPosition = index + 1;
fromPosition <= size;
++fromPosition)
items[translate(fromPosition - 1)] = items[translate(fromPosition)];
--size; // decrease the size of the list by one
} // end if
} // end remove
void List::retrieve(int index, ListItemType& dataItem,
bool& success) const
{
success = (index >= 1) && (index <= size);
if (success)
dataItem = items[translate(index)];
}
int List::translate(int index) const
{
return index - 1;
}
List List::selectionSort(List selectList)
{
return selectList;
}
int main()
{
ListItemType insertType = "listItem1";
ListItemType retrieveType = "listitem2";
int numberofitems;
cout << "Please enter the number of data items:" << endl;
cin >> numberofitems;
cout << endl;
cout << "Please enter the data items, one per line:" << endl;
int listofitems[numberofitems];
List myArrayList;
cout << myArrayList.getLength() << endl;
if (myArrayList.isEmpty()) // tests before
{
cout << "This list is empty \n" << endl;
}
else
{
cout << "List is not empty! \n"<< endl;
}
bool mainsucc = true;
for (int i = 0; i<numberofitems; i++)
{
cout << "Enter number " << i + 1 << " : " << endl;
cin >> listofitems[i];
}
for (int i =0; i <numberofitems; i++){
myArrayList.insert(listofitems[i], insertType, mainsucc);}
cout << "Size of the list is : " << myArrayList.getLength() << endl;
/*for (int i=0; i<mainarraylistsize; i++)
{
cout << myArrayList.retrieve(listofitems[i], retrieveType, mainsucc);
}*/
if (myArrayList.isEmpty()) // tests after
{
cout << "This list is empty \n" << endl;
}
else
{
cout << "List is not empty! \n"<< endl;
}
return 1;
}
have MAX_LIST == 0 means that success will always be false in your insert function.