Function template has already been defined? - c++

In the attached code, I can't get beyond the error function template has already been defined for every function in my class file.
I have been all through it and can't figure out where the functions are already defined anywhere. Note that this code was assembled while going through the chapters of a book, just trying to create functional code to start off with.
BagInterface.h:
/** #file BagInterface.h */
#ifndef BAG_INTERFACE_
#define BAG_INTERFACE_
#include <vector>
using std::vector;
template<class ItemType>
class BagInterface
{
public:
/** Gets the current number of entries in this bag.
#return The integer number of entries currently in the bag. */
virtual int getCurrentSize() const = 0;
/** See whether this bag is empty.
#return True if the bag is empty, or false if not. */
virtual bool isEmpty() const = 0;
/** Adds a new entry to this bag.
#post If successful, newEntry is stored in the bag and
the count of items in the bag has increased by 1.
#param newEntry The object to be addedd as a new entry.
#return True if addition was successful, or false if not. */
virtual bool add(const ItemType& newEntry) = 0;
/** Removes one occurrence of a given entry from this bag.
if possible.
#post If successful, anEntry has been removed from the bag
and the count of items in the bag has decreased by 1.
#param anEntry The entry to be removed.
#return True if removal was successful, or false if not. */
virtual bool remove(const ItemType& anEntry) = 0;
/** Removes all entries from this bag.
#post Bag contains no items, and the count of the items is 0. */
virtual void clear() = 0;
/** Counts the number of times a given entry appears in this bag.
#param anEntry The entry to be counted.
#return The number of times anEntry appears in the bag. */
virtual int getFrequencyOf(const ItemType& anEntry) const = 0;
/** Tests whether this bag contains a given entry.
#param anEntry The entry top locate.
#return True if bag contains anEntry, or False otherwise. */
virtual bool contains(const ItemType& anEntry) const = 0;
/** Empties and then fills a given vector with all entries that
are in this bag.
#return A vector containing copies of all the entries in this bag. */
virtual vector<ItemType> toVector() const = 0;
/** Destroys this bag and frees its assigned memory. */
virtual ~BagInterface() { }
}; // end BagInterface
#endif
ArrayBag.h:
/** #file ArrayBag.h */
#ifndef ARRAY_BAG_
#define ARRAY_BAG_
#include "BagInterface.h"
template<class ItemType>
class ArrayBag : public BagInterface<ItemType>
{
private:
static const int DEFAULT_CAPACITY = 6;
ItemType items[DEFAULT_CAPACITY];
int itemCount;
int maxItems;
int getIndexOf(const ItemType& target, int searchIndex) const;
int countFrequency(const ItemType& target, int searchIndex) const;
public:
ArrayBag();
int getCurrentSize() const;
bool isEmpty() const;
bool add(const ItemType& newEntry);
bool remove(const ItemType& anEntry);
void clear();
bool contains(const ItemType& anEntry) const;
int getFrequencyOf(const ItemType& anEntry) const;
vector<ItemType> toVector() const;
};
#include "ArrayBag.cpp"
#endif
ArrayBag.cpp:
#include "ArrayBag.h"
template<class ItemType>
ArrayBag<ItemType>::ArrayBag() : itemCount(0), maxItems(DEFAULT_CAPACITY)
{
}
template<class ItemType>
int ArrayBag<ItemType>::getIndexOf(const ItemType& target, int searchIndex) const
{
int result = -1;
if (searchIndex < itemCount)
{
if (items[searchIndex] == target)
{
result = searchIndex;
}
else
{
result = getIndexOf(target, searchIndex + 1);
}
}
return result;
}
template<class ItemType>
bool ArrayBag<ItemType>::add(const ItemType& newEntry)
{
bool hasRoomToAdd = (itemCount < maxItems);
if (hasRoomToAdd)
{
items[itemCount] = newEntry;
itemCount++;
}
return hasRoomToAdd;
}
template<class ItemType>
vector<ItemType> ArrayBag<ItemType>::toVector() const
{
vector<ItemType> bagContents;
for (int i = 0; i < itemCount; i++)
bagContents.push_back(items[i]);
return bagContents;
}
template<class ItemType>
int ArrayBag<ItemType>::getCurrentSize() const
{
return itemCount;
}
template<class ItemType>
bool ArrayBag<ItemType>::isEmpty() const
{
return itemCount == 0;
}
template<class ItemType>
bool ArrayBag<ItemType>::remove(const ItemType& anEntry)
{
int locatedIndex = getIndexOf(anEntry, 0);
bool canRemoveItem = !isEmpty() && (locatedIndex > 1);
if (canRemoveItem)
{
itemCount--;
items[locatedIndex] = items[itemCount];
}
return canRemoveItem;
}
template<class ItemType>
void ArrayBag<ItemType>::clear()
{
itemCount = 0;
}
template<class ItemType>
int ArrayBag<ItemType>::getFrequencyOf(const ItemType& anEntry) const
{
return countFrequency(anEntry, 0);
}
template<class ItemType>
int ArrayBag<ItemType>::countFrequency(const ItemType& target, int searchIndex) const
{
int frequency = 0;
if (searchIndex < itemCount)
{
if (items[searchIndex] == target)
{
frequency = 1 + countFrequency(target, searchIndex + 1);
}
else
{
frequency = countFrequency(target, searchIndex + 1);
}
}
return frequency;
}
template<class ItemType>
bool ArrayBag<ItemType>::contains(const ItemType& anEntry) const
{
bool found = false;
int curIndex = 0;
while (!found && (curIndex < itemCount))
{
if (anEntry == items[curIndex])
found = true;
else
curIndex++;
}
return found;
}
Bag.cpp:
#include <iostream>
#include <string>
#include "ArrayBag.h"
using std::cout;
using std::endl;
void displayBag(ArrayBag<std::string>& bag)
{
cout << "The bag contains " << bag.getCurrentSize() << " items:" << endl;
vector<std::string> bagItems = bag.toVector();
int numberOfEntries = (int)bagItems.size();
for (int i = 0; i < numberOfEntries; i++)
{
cout << bagItems[i] << " ";
}
cout << endl << endl;
}
void bagTester(ArrayBag<std::string>& bag)
{
cout << "isEmpty: returns " << bag.isEmpty() << "; should be 1 (true)" << endl;
displayBag(bag);
std::string items[] = { "one","two", "three", "four", "five", "one" };
cout << "Add 6 items to the bag: " << endl;
for (int i = 0; i < 6; i++)
{
bag.add(items[i]);
}
displayBag(bag);
cout << "isEmpty: returns " << bag.isEmpty() << "; should be 0 (false)" << endl;
cout << "getCurrentSize: returns " << bag.getCurrentSize() << "; should be 6" << endl;
cout << "Try to add another entry: add(\"extra\") returns " << bag.add("extra") << endl;
}
int main()
{
ArrayBag<std::string> bag;
cout << "Testing the Array-Based Bag:" << endl;
cout << "The initial bag is empty." << endl;
bagTester(bag);
cout << "All done!" << endl;
std::cin.get();
return 0;
}

Can you please show the makefile, environment, compiler ? I've compiled it whitout problems, I'm using qt creator IDE under windows(mingw32), and the makefile is created automaticly by qmake, so, I supouse that your problem may be in the makefile, I know that it is a comment, but due to my reputation I am not able to make comments, so, after you show the makefile I will can help you.
please avoid mark as negative this answer, I am tryining of help, and increase my reputation. if it answer is not contructive please, let me know and I will remove it.
the output of for code is :
output

I've reproduced your problem and understand what's going on. The unusual construct with include ArrayBag.cpp works fine, as long as you don't compile it, and just use it "as a header". But it's content must appear only once in each translation unit. That's why we have include guards: Any file you #include should have include guards, and ArrayBag.cpp dosn't. Here's how it goes:
You compile Arraybag.cpp, which
includes the declarations in ArrayBag.h Fine, but
ArrayBag.h then includes Arraybag.cpp, which does not have its own include guard
The definitions are parsed, and after the end of Arraybag.cpp, parsing continues back at the end of ArrayBag.h .
We are now done with the first line of the compilation of ArrayBag.cpp, but we are still parsing it: and we go through the rest of ArrayBag.cpp again.
You can still compile ArrayBag.cpp, for the sake of it:
ArrayBag.cpp
// would just be
#include "ArrayBagDefinitions.h"
And ArrayBagDefinitions.h would be your old ArrayBag.cpp file, but with include guards. Your code then compiles fine with vs2017.

In your book, did they mention not to compile ArrayBag.cpp?
In C++, the compiler generates code when a template class is instantiated. Our trusty friend can't do this without a definition. For this reason, the definition needs to be available at compile time (there's more reasons why). For readability, you'll often see people separate the declaration of a template class from the definition.
As the book has shown you, we can take advantage of #include to supply the definition to the compiler while still separating the two.
The caveat here is that you cannot compile the files you used to separate the definition. Depending on whether ArrayBag.cpp is compiled before ArrayBag.h is included somewhere else, the compiler will have a hizzy fit when he finds out that you already tried to define ArrayBag.
Alternatively, you can add an include guard in ArrayBag.cpp, which will prevent the compiler from attempting define ArrayBag again during compilation of ArrayBag.cpp, but I don't advise this. It will add unnecessary time during compilation. After all, we're abusing the simplicity of #include here to mitigate a pain point in the requirements of the compiler.
If you're using Visual Studio, you can treat a .cpp file as a header file by right clicking on the file in the solution explorer > Properties > General > Excluded From Build: Yes

Related

Implementing Circular Array Queue

I am to implement a Circular Array Queue But I a having logical errors and I am not getting the correct result. I need help implementing bool dequeue() in ArrayQueueP4.h. I doubt if it is correct.
.
I have tried different solutions as well as search through previous questions on stack overflow and online yet it did not give me any ideas on what I am looking for
#ifndef ARRAY_QUEUE_P4_
#define ARRAY_QUEUE_P4_
#include "QueueInterface.h"
#include "PrecondViolatedExcept.h"
template<class ItemType>
class ArrayQueueP4 : public QueueInterface<ItemType>
{
private:
static const int DEFAULT_CAPACITY = 50;
ItemType items[DEFAULT_CAPACITY + 1]; // Array of queue items
int front; // Index to front of queue
int back; // Index to back of queue
public:
ArrayQueueP4() : front(DEFAULT_CAPACITY),
back(DEFAULT_CAPACITY) {};
// Copy constructor and destructor supplied by compiler
bool isEmpty() const;
bool enqueue(const ItemType& newEntry);
bool dequeue();
/** #throw PrecondViolatedExcept if queue is empty. */
ItemType peekFront() const;
};
ArrayQueueP4.h is the header file for ArrayQueueP4.cpp
#include "ArrayQueueP4.h";
#include "PrecondViolatedExcept.h";
using namespace std;
template <class ItemType>
bool ArrayQueueP4 <ItemType>::isEmpty() const {
return (front == back);
}
template <class ItemType>
bool ArrayQueueP4 <ItemType>::enqueue(const ItemType& newEntry) {
if (!isEmpty())
back = (back + 1) % DEFAULT_CAPACITY;
items[back] = newEntry;
back++;
return true;
}
template<class ItemType>
bool ArrayQueueP4 <ItemType> ::dequeue() {
bool result = false;
if (!isEmpty()) {
front = (front + 1) % DEFAULT_CAPACITY;
front--;
result = true;
}
return result;
}
template<class ItemType>
ItemType ArrayQueueP4<ItemType>::peekFront() const {
if (isEmpty())
throw PrecondViolatedExcept("peekFront() called with an empty queue.");
else
return items[front];
}
HERE is my main file main.cpp to test my code
#include <iostream>
#include "ArrayQueueP4.cpp";
using namespace std;
int main() {
ArrayQueueP4<int> AP;
AP.enqueue(1);
AP.enqueue(2);
AP.enqueue(3);
/*LinkedQueueP1<int> LP;
LP.enqueue(1);
LP.enqueue(2);*/
cout << "PEEK FRONT: " << AP.peekFront();
//cout << "PEEK FRONT: " << LP.peekFront();
system("pause");
return 0;
}
Based on my main program file, the output supposed to now 1 when I call the enqueue function. But instead of getting 2 as my answer, I am getting -858993460 as my result when I delete the first item using dequeue(). I do not know if that is how Queues behave but isn't the second number supposed to be the next first item in line when I delete the first number?
According to your description, your front and back defines a range, such that front is the first element available in the queue, and back is the "pass-the-end" index. Then according to those definition the code should look like this:
template <class ItemType>
bool ArrayQueueP4 <ItemType>::enqueue(const ItemType& newEntry) {
// Check if queue is full
if ((back + 1) % (DEFAULT_CAPACITY + 1) == front) return false;
// Append element at one-pass-end position
items[back] = newEntry;
// Update the one-pass-end index (back)
// All your modulo operation should be dealing with DEFAULT_CAPACITY + 1
// because that is the size of your array
back = (back + 1) % (DEFAULT_CAPACITY + 1);
return true;
}
template<class ItemType>
bool ArrayQueueP4 <ItemType> ::dequeue() {
// Dequeue fail if the queue is empty
if (isEmpty()) return false;
front = (front + 1) % (DEFAULT_CAPACITY + 1);
return true;
}
Also, as a reminder, your code does not take resource management in to account (although it works for most types and doesn't seem to make any mistakes). When an item is dequeued, it's corresponding resources should be released. As an exercise, think about the scenario where ItemType is std::unique_ptr (or std::shared_ptr). This is probably not what your teacher wants, but it is a good practice.

Unknown Syntax errors in linkedlist Sort program

Assignment was to create a sort function for linked list. Was able to code it, but I am getting a ton of unknown syntax errors. I suspect it could be Visual Studio (professor requires it), but I want to see what you guys think. Most of the errors lie in the header file (SortedList.h), however my professor provided this piece of code, so it doesnt make sense that it doesnt work.
EDIT:
Errors include:
-Missing type specifier - int assumed Note: C++ does not support default int
(sortedlist.h Line:4)
-Syntax error missing ; before identifier ItemType (sortedlist.h Line:4)
-'string' ambiguous symbol (sortedlistprogram.cpp Line:12)
-Syntax error: Identifier 'itemType' (Sortedlist.h Line 14)
-Unexpected token(s) proceeding ';' (sortedlist.h Line 34)
//SortedList.h (header file)
#include <string>
const int MAX_ITEMS = 20;
typedef string ItemType;
class SortedList
{
public:
SortedList();
// Constructor
// Post: Empty list is created.
// Action responsibilities
void Insert(ItemType item);
// Pre: The list is not full;
// Post: item is in the list; list is stored in
// increasing order.
void PrintList();
// Post: If the list is not empty, the elements are
// printed on the screen in increasing order;
// otherwise "The list is empty" is
// printed on the screen.
// Knowledge responsibilities
int GetLength();
// Post: return value is the number of items in the list.
bool IsEmpty();
// Post: returns true if list is empty; false otherwise.
bool IsFull();
// Post: returns true if there is no more room in the
// list; false otherwise.
private:
int length;
ItemType values[MAX_ITEMS];
};
//SortedList.CPP
#include "sortedList.h"
#include <iostream>
#include<string>
#include<algorithm>
using namespace std;
SortedList::SortedList()
{
length = 0;
}
bool SortedList::IsEmpty()
//Function to check if empty
{
if (values->empty())
return true;
return false;
}
bool SortedList::IsFull()
//Function to check if full
{
if (length == MAX_ITEMS)
return true;
return false;
}
void SortedList::Insert(ItemType item)
//Insert function for SortedList
{
if (!IsFull())
{
values[length] = item;
++length;
sort(values, values + length);
}
}
int SortedList::GetLength()
//Function to return length
{
return length;
}
void SortedList::PrintList()
//Function to print list
{
if (IsEmpty())
{
cout << "List is empty" << endl;
}
else
{
for (int index = 0; index < length; ++index)
{
cout << values[index] << endl;
}
cout << endl << "There are " << GetLength() << " items in the list" <<
endl;
}
}
//Driver.CPP
#include "sortedList.h"
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string value;
SortedList list;
list.PrintList();
ifstream file("word.in");
//calls word.in file
if (file.good())
//Checks if file is good
{
while (getline(file, value))
{
list.Insert(value);
}
file.close();
}
list.PrintList();
//Prints list
return 0;
}

delete function of queue

I'm facing a problem with my queue delete function. Please have a look at the following code.
class queueType // public queueADT<Type>
{
public:
const queueType<Type>& operator=(const queueType<Type>&);
bool isEmptyQueue() const;
bool isFullQueue() const;
void initializeQueue(int);
void minusIo(int);
Type & front();
Type & back();
void addQueue(const Type& queueElement);
void addQueueFront(const Type& newElement);
void deleteQueue();
queueType(int queueSize = 100);
queueType(const queueType<Type>& otherQueue);
~queueType();
bool operator== (const queueType<Type>&);
bool operator!= (const queueType<Type>&);
void deleteBackOfQueue();
void printQueue();
void sort();
bool notin(Type f);
void shortest(int);
Type *list;
int count;
Type & any(int);
void deleteany();
private:
int maxQueueSize;
int queueFront;
int queueRear;
bool isEqual(const queueType<Type>&);
};
The below is given my delete queue and print functions.
template<class Type>
void queueType<Type>::deleteQueue()
{
if (!isEmptyQueue())
{
queueFront = ++queueFront % maxQueueSize;
count--;
}
else
cout << "Cannot remove from an empty queue" << endl;
}
Following is the print function.
template
void queueType<Type>::printQueue()
{
for (int i = 0; i<count; i++)
{
cout << list[i];
}
}
I used it in my main function as following.
void main()
{
queueType<int> RQ;
RQ.addQueue(2);
RQ.addQueue(8);
RQ.addQueue(7);
RQ.addQueue(2);
RQ.addQueue(4);
RQ.printQueue();
cout << endl;
RQ.deleteQueue();
RQ.printQueue();
getchar();
}
It is showing the following result.
28724
2872
I don't understand why it is deleting from the end and not from the front. To me code seems fine. Please have a look and let me know.
Since your delete function does not modify "list" your print should not start from zero but from queueFront. An easy way to achieve this is by replacing:
cout << list[i];
with:
cout << list[i+queueFront];
In your printing function.
But you should look into modifying list in some way, while still keeping a pointer to the memory you have to free.

Link List of Class, How to get call toString while Transversing?

I was wondering how I could call the toString() method in my Link List of the class BoxClass. BoxClass has a double length, width and height.
my BoxClass:
class BoxClass{
private:
double length;
double width;
double height;
public:
// Default constructor w/ no parameters
BoxClass(){
length = 0;
width = 0;
height = 0;
}
// Constructor with arguments
BoxClass(double boxLength, double boxWidth, double boxHeight){
length = boxLength;
width = boxWidth;
height = boxHeight;
}
// Setters and Getters
void setLength(double boxLength){
length = boxLength;
}
double getLength(){
return length;
}
void setWidth(double boxWidth){
width = boxWidth;
}
double getWidth(){
return width;
}
void setHeight(double boxHeight){
height = boxHeight;
}
double getHeight(){
return height;
}
// Returns the volume of the boxes
double Volume(){
return (length * width * height);
}
// toString method for boxes, returns "(length) x (width) x (height) string
string toString(){
return ("(" + to_string(length)+ "x" + to_string(width) + "x" + to_string(height) + ")");
}
}; // End of BoxClass() class
LinkNode.h
//Template ListNode class definition.
#ifndef LINKNODE_H
#define LINKNODE_H
template <typename T> class LinkList;
template <typename T> class LinkNode{
friend class LinkNode <T>;
public:
LinkNode(const T &);
T getData()const;
T data;
LinkNode <T> *nextPtr;
};
template <typename T> LinkNode <T>::LinkNode(const T &info):data(info), nextPtr(NULL){
// Empty body
}
template <typename T>T LinkNode<T>::getData()const{
return data;
}
#endif
Main (Creating the class, adding it to Link List
// Create the Box class
BoxClass userBox(length, width, height);
// Add box class to Link List
Box.insertNode(userBox);
Box.print();
LinkList.h print() method
template<typename T>void LinkList<T>::print()const {
// To list off nodes
int counter = 1;
if (isEmpty()) {
cout << "No boxes in list!\n";
} else {
LinkNode<T>*currentPtr = firstPtr;
cout << "Your boxes in increasing order of volume is:\n";
// while (currentPtr) {
while (currentPtr != NULL) {
// Output as "#. (length x width x height)
cout << counter << ". " << currentPtr->data << endl;
printf(" %i. %.2f\n", counter, currentPtr->data);
currentPtr = currentPtr->nextPtr;
counter++;
}
}
}
LinkList.h
//Template LinkList class definition.
#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
#include "LinkNode.h"
using namespace std;
template<typename T> class LinkList {
public:
LinkList();
void addNode(const T &);
void insertNode(const T &);
bool isEmpty() const;
void print() const;
private:
LinkNode<T>*firstPtr;
LinkNode<T>*getNewNode(const T &);
};
template<typename T>LinkList<T>::LinkList() :firstPtr(NULL) {
// Empty body
}
template <typename T>void LinkList<T>::insertNode(const T &value) {
LinkNode<T>*newPtr = getNewNode(value);
bool inserted = false;
if (isEmpty() || (newPtr->data < firstPtr->data)) {
newPtr->nextPtr = firstPtr;
firstPtr = newPtr;
// cout << " " << newPtr->data << " inserted at front of list.\n";
printf(" %.2f inserted at front of list.\n", newPtr->data);
} else {
LinkNode<T>*currentPtr = firstPtr;
while (currentPtr->nextPtr && !inserted) {
if (newPtr->data < currentPtr->nextPtr->data) {
// cout << " " << newPtr->data << " inserted before " << currentPtr->nextPtr->data << ". " << endl;
printf(" %.2f inserted before %.2f.\n", newPtr->data, currentPtr->nextPtr->data);
newPtr->nextPtr = currentPtr->nextPtr;
currentPtr->nextPtr = newPtr;
inserted = true;
} else {
currentPtr = currentPtr->nextPtr;
}
}
if (!inserted) {
currentPtr->nextPtr = newPtr;
printf(" %.2f inserted at the end of list.\n", newPtr->data);
}
}
}
template<typename T>bool LinkList<T>::isEmpty()const {
return firstPtr == NULL;
}
template<typename T>LinkNode<T>*LinkList<T>::getNewNode(const T &value) {
return new LinkNode<T>(value);
}
template<typename T>void LinkList<T>::print()const {
// To list off nodes
int counter = 1;
if (isEmpty()) {
cout << "No boxes in list!\n";
} else {
LinkNode<T>*currentPtr = firstPtr;
cout << "Your boxes in increasing order of volume is:\n";
// while (currentPtr) {
while (currentPtr != NULL) {
// Output as "#. (length x width x height)
cout << counter << ". " << currentPtr->data << endl;
printf(" %i. %.2f\n", counter, currentPtr->data);
currentPtr = currentPtr->nextPtr;
counter++;
}
}
}
#endif
So again, my question is- How do I go about traversing the list and calling the toString() BoxClass method? I tried everything from cout << data.toString() << endl; but that doesn't work. I've been stuck on this for days, can someone help me out?
edit: added LinkList.h
When you write template <typename T> class LinkNode{ you are specifically stating that your node class will have no built-in knowledge of the type of the node that it contains.
You have not shown us your LinkList<T> class, but obviously, the same thing applies to it: since it consists of LinkNode<T> it has to also accept a generic parameter of type <T>, so it cannot have built-in knowledge of the actual type of <T> either.
Therefore, you cannot suddenly introduce a method which has such knowledge. It does not make sense. "It does not compute".
What you need to do instead is add this print() method of yours elsewhere, and make it accept a LinkList<BoxClass>. Then, it will be able to view the LinkNodes as LinkNode<BoxClass>, and it will be able to invoke linkNode.data.toString().
The problem is that your implementation of LinkList<T> class has no way for the client code to go through each node of the list in a loop. What if we don't want to print, but do something else with each box?
In addition, it would look weird if I have a LinkList<Widget>, and I see the text when I call print():
"Your boxes in increasing order of volume is:";
I would say, "what boxes? what volume? I have Widgets, not boxes".
A more complete implementation would look something like this (caveat: This has not been compiled. It is to give you the gist of what you should be doing):
template<typename T> class LinkList {
public:
LinkList();
void addNode(const T &);
void insertNode(const T &);
bool isEmpty() const;
// this is what you're missing from the current implementation
typedef LinkNode<T>* Iterator;
Iterator begin() { return firstPtr; }
Iterator next(Iterator ptr) { return ptr->nextPtr; }
Iterator end() { return NULL; }
private:
LinkNode<T>* firstPtr;
LinkNode<T>* getNewNode(const T &);
};
Then with this, the print function need not be part of the linked list. It can live on the outside:
LinkList<BoxClass> boxList;
//...
void print()
{
if (boxList.isEmpty())
cout << "No boxes in list!\n";
else
{
int counter = 1;
cout << "Your boxes in increasing order of volume is:\n";
// get first box
LinkList<BoxClass>::Iterator curBox = boxList.begin();
// loop until no more boxes
while (curBox != boxList.end())
{
// now use curBox to do whatever you want with this box
BoxClass& b = curBox->getData();
cout << counter << ". " << b.toString();
// go to the next box
curBox = boxList.next(curBox);
counter++;
}
}
}
Note how print is no longer a member of LinkList. Also, note the typedef to give us a "nice" name for the LinkNode pointer that the client uses. The comments should be self-explanatory.
I didn't want to overcomplicate the code by introducing a "real" iterator (i.e. overloaded ++), but that operator would replace the LinkList<T>:::next() function call. I leave that to you as an additional exercise.

Object of abstract class type "set<std::string>" is not allow:

I'm using Visual Studios and when I declare a type, its say:
"Error: Object of abstract class type "set< std::string >" is not allow:
Pure virtual function "setinterface::GetCurrentSize [with type=std::string]" has no overrider"
#include <iostream> // For cout and cin
#include <string> // For string objects
#include "set.h" // For ADT bag
#include "setinterface.h" // For ADT setinterface
#include <vector> // for vector objects
using namespace std;
int main()
{
string clubs[] = { "Joker", "Ace", "Two", "Three",
"Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack",
"Queen", "King" };
// Create our bag to hold cards.
set<string> grabBag;
By the time I get to get to set < string > grabBag is when i get this error. Here is the rest of my code
set.h
#ifndef TEACH_CSCI235_BAGADT_BAG_H_
#define TEACH_CSCI235_BAGADT_BAG_H_
#include "setinterface.h"
template<class ItemType>
class set : public setinterface<ItemType>
{
public:
set(const ItemType& an_item)Íž
int GetCurrentSize() const;
bool IsEmpty() const;
bool Add(const ItemType& new_entry);
bool Remove(const ItemType& an_entry);
void Clear();
bool Contains(const ItemType& an_entry) const;
vector<ItemType> ToVector() const;
private:
int GetIndexOf(const ItemType& target) const;
static const int kDefaultBagSize_ = 6;
ItemType items_[kDefaultBagSize_]; // array of bag items
int item_count_; // current count of bag items
int max_items_; // max capacity of the bag
// Returns either the index of the element in the array items that
// contains the given target or -1, if the array does not contain
// the target.
}; // end Bag
#endif // TEACH_CSCI235_BAGADT_BAG_H_
template<class ItemType>
set<ItemType>::set() : item_count_(0), max_items_(kDefaultBagSize_)
{
return items_[item_count_];
} // end default constructor
template<class ItemType>
int set<ItemType>::GetCurrentSize() const
{
return item_count_;
} // end getCurrentSize
template<class ItemType>
bool set<ItemType>::IsEmpty() const
{
return item_count_ == 0;
} // end isEmpty
template<class ItemType>
bool set<ItemType>::Add(const ItemType& new_entry)
{
bool has_room_to_add = item_count_ < max_items_;
//compares the new entry to every item in item_ and if there is a duplicate, the loop breaks and nothing is added.
if (has_room_to_add)
{
for ( int i =0; i < max_items_; i++)
{
if (items_[i] == new_entry)
break; //ends loop
else if (i==5)
{
items_[item_count_] = new_entry;
item_count_++;
break; //ends loop
} // end if
} // end for
} //end if
return has_room_to_add;
} // end add
template<class ItemType>
bool set<ItemType>::Remove(const ItemType& an_entry)
{
int located_index = GetIndexOf(an_entry);
bool can_remove_item = !IsEmpty() && (located_index > -1);
if (can_remove_item)
{
item_count_--;
items_[located_index] = items_[item_count_];
} // end if
return can_remove_item;
} // end remove
template<class ItemType>
void set<ItemType>::Clear()
{
item_count_ = 0;
} // end clear
template<class ItemType>
bool set<ItemType>::Contains(const ItemType& an_entry) const
{
return GetIndexOf(an_entry) > -1;
} // end contains
template<class ItemType>
vector<ItemType> set<ItemType>::ToVector() const
{
vector<ItemType> bag_contents;
for (int i = 0; i < item_count_; i++)
bag_contents.push_back(items_[i]);
return bag_contents;
} // end toVector
template<class ItemType>
int set<ItemType>::GetIndexOf(const ItemType& target) const
{
bool found = false;
int result = -1;
int search_index = 0;
// if the bag is empty, item_count is zero, so loop is skipped
while (!found && (search_index < item_count_))
{
if (items_[search_index] == target)
{
found = true;
result = search_index;
}
else
{
search_index++;
} // end if
} // end while
return result;
} // end getIndexOf
here is all of setinterface.h
#ifndef TEACH_CSCI235_BAGADT_BAGINTERFACE_H_
#define TEACH_CSCI235_BAGADT_BAGINTERFACE_H_
#include <vector>
#include <cstddef>
using namespace std;
template<class ItemType>
class setinterface
{
public:
/** Gets the current number of entries in this bag.
#return The integer number of entries currently in the bag. */
virtual int GetCurrentSize() const = 0;
/** Sees whether this bag is empty.
#return True if the bag is empty, or false if not. */
virtual bool IsEmpty() const = 0;
/** Adds a new entry to this bag.
#post If successful, newEntry is stored in the bag and
the count of items in the bag has increased by 1.
#param new_entry The object to be added as a new entry.
#return True if addition was successful, or false if not. */
virtual bool Add(const ItemType& new_entry) = 0;
/** Removes one occurrence of a given entry from this bag,
if possible.
#post If successful, anEntry has been removed from the bag
and the count of items in the bag has decreased by 1.
#param an_entry The entry to be removed.
#return True if removal was successful, or false if not. */
virtual bool Remove(const ItemType& an_entry) = 0;
/** Removes all entries from this bag.
#post Bag contains no items, and the count of items is 0. */
virtual void Clear() = 0;
/** Tests whether this bag contains a given entry.
#param an_entry The entry to locate.
#return True if bag contains anEntry, or false otherwise. */
virtual bool Contains(const ItemType& an_entry) const = 0;
/** Empties and then fills a given vector with all entries that
are in this bag.
#return A vector containing all the entries in the bag. */
virtual vector<ItemType> ToVector() const = 0;
}; // end BagInterface
#endif // TEACH_CSCI235_BAGADT_BAGINTERFACE_H_
I started getting this error right after i tried to create a constructor in the set class and when I went to save it, it gave me a notice that it was gonna use something else in order to save my data, I didn't pay much attention to it but I think that may have something to do with this error.
I'm also suppose to "add a constructor that constructs a Set for a single item:" according to my assignment so my constructor might be a good place to look. I'm not even sure if I did it correctly.
I appreciate any help. Thankyou!