Question
C++ Object Oriented Programming - You will be creating a singly-linked list class template. I've been given a skeleton of the header of singly-linked list
C++ Object Oriented Programming - You will be creating a singly-linked list class template.
I've been given a "skeleton" of the header of singly-linked list class template. I'm also allowed to add any helper functions to the class, but everything in the header is required. The list will also be expected to hold Money objects, all of the code for the Money class is included. Everything below the "SLList.hpp" code are the test files used to test out the entire SLList class. I'll label all of those with bold names to signify with a new file is being used.
SLList.hpp
// It's a template class
class SLList {
public:
// Default Constructor
// Constructor that takes first item for list
// It shall not be possible to create copies or assign directly to the linked list
// Destructor
// begin()
// end()
// A function called empty that lets you know if the list is empty or not
// A function called size that tells you how big the list is
// A function called front that returns the key value of the front node (return by value only)
// A function called push_back that adds a key to the end of the list
// A function called erase that takes as a parameter an iterator that indicates the Node to be erased.
// It returns an iterator that indicates the position after the node that was erased
// See the list class function of the same name at cplusplus.com
// A function called clear that erases the list, but leaves the list object in a viable state
private:
// Declare your Node class privately here
// A pointer to the first node in the list
};
// Probably a good spot for the iterator class declaration
// It is contained within a template class
class SLList::iterator {
public:
// Constructor that takes a Node pointer
// Overloaded postfix and prefix increment operators
// No decrements, this will be a forward-only iterator
// Overloaded de-reference operator, returns by value only
// Overloaded equality operator
// Overloaded inequality operator
private:
// Node pointer (resource being managed by the iterator)
};
// Implementations of classes go here
End of SLList.hpp
Beginning of main.cpp
#include #include #include "Money.hpp" #include "SLList.hpp" #include "test_interface.hpp"
int main() { runTests();
return 0; }
End of main.cpp
Beginning of Money.hpp
#ifndef MONEY_HPP
#define MONEY_HPP
#include
class Money {
public:
Money();
Money(int d, int c);
Money(int d);
Money(double m);
int getPennies() const;
bool isNegative() const;
const Money operator -() const;
Money& operator ++();
const Money operator ++(int);
Money& operator --();
const Money operator --(int);
friend const Money operator +(const Money &left, const Money &right);
friend const Money operator -(const Money &left, const Money &right);
friend const Money operator *(const Money &left, const int right);
friend const Money operator *(const int left, const Money &right);
friend const Money operator *(const Money &left, const double right);
friend const Money operator *(const double left, const Money &right);
friend bool operator <(const Money &left, const Money &right);
friend bool operator <=(const Money &left, const Money &right);
friend bool operator >(const Money &left, const Money &right);
friend bool operator >=(const Money &left, const Money &right);
friend bool operator ==(const Money &left, const Money &right);
friend bool operator !=(const Money &left, const Money &right);
friend std::ostream& operator <<(std::ostream &outStream, const Money &right);
friend std::istream& operator >>(std::istream &inStream, Money &right);
private:
int dollars;
int cents;
// Helper functions
int makePennies() const; // EXTRA
void validate(); // EXTRA
};
#endif
End of Money.hpp
Beginning of Money.cpp
#include
#include
#include
#include
#include
#include "Money.hpp"
// MEMBER FUNCTIONS
Money::Money()
: dollars(0)
, cents(0)
{
}
Money::Money(int d, int c)
: dollars(d)
, cents(c)
{
validate();
}
Money::Money(int d)
: dollars(d)
, cents(0)
{
}
Money::Money(double m)
{
int pennies = round(m * 100);
dollars = pennies / 100;
cents = pennies % 100;
}
int Money::getPennies() const
{
return makePennies();
}
bool Money::isNegative() const
{
if (dollars < 0 || cents < 0)
return true;
else
return false;
}
const Money Money::operator -() const
{
int negDollars = -dollars;
int negCents = -cents;
return Money(negDollars, negCents);
}
Money& Money::operator ++()
{
++dollars;
if (dollars > 0 && cents < 0)
cents *= -1;
return *this;
}
const Money Money::operator ++(int)
{
Money temp = *this;
++(*this);
return temp;
}
Money& Money::operator --()
{
--dollars;
if (dollars < 0 && cents > 0)
cents *= -1;
return *this;
}
const Money Money::operator --(int)
{
Money temp = *this;
--(*this);
return temp;
}
int Money::makePennies() const
{
return (dollars * 100) + cents;
}
void Money::validate()
{
if (dollars < 0 && cents > 0)
cents *= -1;
else if (cents < 0 && dollars > 0)
dollars *= -1;
}
// NON-MEMBER FRIEND FUNCTIONS
const Money operator +(const Money &left, const Money &right)
{
int leftPennies = left.makePennies();
int rightPennies = right.makePennies();
int sumPennies = leftPennies + rightPennies;
return Money(sumPennies / 100, sumPennies % 100);
}
const Money operator -(const Money &left, const Money &right)
{
int leftPennies = left.makePennies();
int rightPennies = right.makePennies();
int difference = leftPennies - rightPennies;
return Money(difference / 100, difference % 100);
}
const Money operator *(const Money &left, const int right)
{
int leftPennies = left.makePennies();
int product = leftPennies * right;
return Money(product / 100, product % 100);
}
const Money operator *(const int left, const Money &right)
{
return (right * left);
}
const Money operator *(const Money &left, const double right)
{
int leftPennies = left.makePennies();
double product = round(static_cast(leftPennies) * right);
int finalPennies = static_cast(product);
return Money(finalPennies / 100, finalPennies % 100);
}
const Money operator *(const double left, const Money &right)
{
return (right * left);
}
bool operator <(const Money &left, const Money &right)
{
if (left.dollars < right.dollars)
return true;
else if (left.dollars == right.dollars && left.cents < right.cents)
return true;
else
return false;
}
bool operator <=(const Money &left, const Money &right)
{
return (!(right < left));
}
bool operator >(const Money &left, const Money &right)
{
return (right < left);
}
bool operator >=(const Money &left, const Money &right)
{
return (!(left < right));
}
bool operator ==(const Money &left, const Money &right)
{
return (!(left < right) && !(right < left));
}
bool operator !=(const Money &left, const Money &right)
{
return !(left == right);
}
std::ostream& operator <<(std::ostream &outStream, const Money &right)
{
bool neg = right.isNegative();
std::string value;
if (neg)
value.push_back('(');
value = value + "$" + std::to_string(abs(right.dollars)) + ".";
if (abs(right.cents) < 10)
value.push_back('0');
value = value + std::to_string(abs(right.cents));
if (neg)
value.push_back(')');
outStream << value;
return outStream;
}
std::istream& operator >>(std::istream &inStream, Money &right)
{
std::string input;
inStream >> input;
// Flush stream after getting what I need
inStream.ignore(std::numeric_limits::max(), ' ');
if (input.at(0) == '$') {
input.erase(0, 1);
}
std::string::size_type sz;
double value = std::stod(input, &sz);
if (sz != input.length())
value = 0;
int pennies = round(value * 100);
right.dollars = pennies / 100;
right.cents = pennies % 100;
return inStream;
}
End of Money.cpp
Beginning of tests.hpp
#ifndef UGLYTESTING_HPP #define UGLYTESTING_HPP
#include #include
template bool IS_EQUAL(T val, T testVal) { return val == testVal; }
bool EXPECT_TRUE(bool test) { return test == true; }
bool EXPECT_FALSE(bool test) { return test == false; }
#endif
End of tests.hpp
Beginning of testFuncs.hpp
#ifndef TESTFUNCS_HPP
#define TESTFUNCS_HPP
#include
#include "SLList.hpp"
#include "tests.hpp"
#include "Money.hpp"
bool constbegderef()
{
SLList obj(5);
SLList::iterator it = obj.begin();
return IS_EQUAL(5, *it);
}
bool testfront()
{
SLList obj("MONDO");
return EXPECT_TRUE(obj.front() == "MONDO");
}
bool testPushBack()
{
SLList obj;
obj.push_back(3.14);
return IS_EQUAL(3.14, obj.front());
}
bool testErase(char p)
{
SLList obj;
obj.push_back("HELLO");
obj.push_back("CRUEL");
obj.push_back("WORLD");
obj.push_back("HERE'S");
obj.push_back("JOHNNY");
auto it = obj.begin();
switch (p) {
case 'b':
it = obj.erase(it);
return IS_EQUAL(std::string("CRUEL"), obj.front());
break;
case 'm':
++it;
it = obj.erase(it);
return IS_EQUAL(std::string("WORLD"), *it);
break;
case 'e':
while (*it != std::string("JOHNNY") && it != obj.end())
++it;
it = obj.erase(it);
return nullptr == it;
break;
default:
std::cout << "Default case? ";
return false;
break;
}
}
bool testClear()
{
SLList obj;
obj.push_back(7.67);
obj.push_back(5);
obj.push_back(Money(3, 50));
obj.clear();
obj.push_back(4);
return IS_EQUAL(Money(4), obj.front());
}
bool testSize(char t)
{
SLList obj;
obj.push_back(4.5);
obj.push_back(6);
obj.push_back(Money(7, 37));
auto it = obj.begin();
switch (t) {
case 'p':
obj.push_back(800);
return IS_EQUAL(4, obj.size());
break;
case 'e':
it = obj.erase(it);
return IS_EQUAL(2, obj.size());
break;
default:
std::cout << "Default case? ";
return false;
break;
}
}
bool testPostfixInc()
{
SLList obj;
std::stringstream ss;
for (int i = 5; i < 8; i++)
obj.push_back(i);
for (auto it = obj.begin(); it != obj.end(); it++)
ss << *it;
return IS_EQUAL(std::string("567"), ss.str());
}
bool testEQUIVT()
{
SLList obj;
obj.push_back(3.14);
obj.push_back(5.67);
obj.push_back(88);
auto itONE = obj.begin();
auto itTWO = obj.begin();
itONE++;
itTWO++;
return itONE == itTWO;
}
bool testEQUIVF()
{
SLList obj;
obj.push_back(3.14);
obj.push_back(5.67);
obj.push_back(88);
auto itONE = obj.begin();
auto itTWO = obj.begin();
itTWO++;
return !(itONE == itTWO);
}
bool testINEQUIVT()
{
SLList obj;
obj.push_back(3.14);
obj.push_back(5.67);
obj.push_back(88);
auto itONE = obj.begin();
auto itTWO = obj.begin();
itTWO++;
return itONE != itTWO;
}
bool testINEQUIVF()
{
SLList obj;
obj.push_back(3.14);
obj.push_back(5.67);
obj.push_back(88);
auto itONE = obj.begin();
auto itTWO = obj.begin();
itONE++;
itTWO++;
return !(itONE != itTWO);
}
#endif
End of testFuncs.hpp
Beginning of test_interface.hpp
#ifndef TEST_INTERFACE_HPP #define TEST_INTERFACE_HPP
#include #include #include "testFuncs.hpp" #include "tests.hpp" #include "SLList.hpp"
void runTests() { using std::cout; using std::left; using std::setw; using std::endl;
const int COL = 70;
char prev = cout.fill('.'); cout << "SLList Class Tests "; cout << setw(COL) << left << "Contructor (First Item Provided), begin(), & iterator::operator*" << constbegderef() << endl; cout << setw(COL) << left << "Empty()" << EXPECT_TRUE(SLList().empty()) << endl; cout << setw(COL) << left << "front()" << testfront() << endl; cout << setw(COL) << left << "Basic size()" << EXPECT_TRUE(SLList('a').size() == 1) << endl; cout << setw(COL) << left << "Default Constructor" << EXPECT_TRUE(SLList().size() == 0) << endl; cout << setw(COL) << left << "push_back()" << testPushBack() << endl; cout << setw(COL) << left << "erase() (first)" << testErase('b') << endl; cout << setw(COL) << left << "erase() (middle) & iterator operator++()" << testErase('m') << endl; cout << setw(COL) << left << "erase() (last)" << testErase('e') << endl; cout << setw(COL) << left << "clear()" << testClear() << endl; cout << setw(COL) << left << "size() (after push_back)" << testSize('p') << endl; cout << setw(COL) << left << "size() (after erase)" << testSize('e') << endl; cout << setw(COL) << left << "iterator operator++(int)" << testPostfixInc() << endl; cout << setw(COL) << left << "iterator Equality (T)" << testEQUIVT() << endl; cout << setw(COL) << left << "iterator Equality (F)" << testEQUIVF() << endl; cout << setw(COL) << left << "iterator Inequality (T)" << testINEQUIVT() << endl; cout << setw(COL) << left << "iterator Inequality (F)" << testINEQUIVF() << endl;
cout.fill(prev); }
#endif
End of test_interface.hpp
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started