Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

c++ Design an Enhanced PlayList Program All the code I will give to you. The main.cpp cannot be changed and that must be used. The

c++

Design an Enhanced PlayList Program

All the code I will give to you. The main.cpp cannot be changed and that must be used. The expected output is also shared

The only thing that I need help with is creating PlayLIst.cpp and PlayLIst.h. The files should output the expected answer (it is included)

It is important that you only give me code for these two files and do not change the main.cpp.

I will give you the code for the rest of the files.

I have done all the code but i only need help with PlayLIst.cpp and PlayLIst.h. I am still sending all the code i have written. however i only need help with playlist.cpp and .h.

The following is the part i need help with.

Class PlayList

The bulk of the work for this project is in the redesign/reimplementation of your PlayList class. PlayList willnow inherit from (is a derived class of) LinkedSet. So it will inherit all of LinkedSet's public and protected members, and these will automatically be available to PlayList through inheritance... that saves you a lot of work, pretty cool huh!?! But you do want to change a few things (name all methods and objects exactly as described below, test your methods incrementally , do not override any methods other than the ones specified below):

1. PlayList will only ever hold Songs, not some arbitrary ItemType, so it will inherit from LinkedSet class PlayList : public LinkedSet

2. PlayList will have a single private data member: a pointer to its last node (I will explain why below) Node* tail_ptr_; // Pointer to last node

3. Recall: constructors and destructors are not inherited, so you must ALWAYS declare and implement these in a derived class. Base class constructors are called before derived class constructors, so all LinkedSet derived members will be taken care of. PlayList constructors need to make sure to correctly initialize the derived class private data members (tail_ptr_).

PlayList(); //default constructor

PlayList(const Song& a_song); //parameterized constructor

Wen implementing the copy constructor beware of slicing!

Moreover, keep in mind that LinkedSet's copy constructor will make a deep copy of the chain, but it will only take care of copying the base-class data members.

PlayList's copy constructor will also need to correctly point tail_ptr_ to the last node in the copied chain, unless the chain is empty.

To do so, you will also write a private member functiongetPointerToLastNode that traverses the chain and returns a pointer to the last node.

The copy constructor will call this private function to correctly set the value of tail_ptr_ so that it points to the last node.

Once again, the copy constructor is public while getPointerToLastNode is private

PlayList(const PlayList& a_play_list); // copy constructor

Node* getPointerToLastNode() const;

Derived class destructors are called before base class destructors.

LinkedSet's constructor will take care of correctly deleting all the nodes thus returning memory to the system.

PlayList's destructor needs to unloop()(described below) first, otherwise LinkedSet's destructor will not behave correctly if the chain is looped.

~PlayList(); // Destructor

4. A PlayList is like a Set in that you don't want to have the same song play multiple times. It would be nice, however, to add songs at the end of the PlayList instead of adding at the beginning like Set does. So you decide to override add() to do just that. Just as in Set you always have access to the first node through head_ptr_ . Conveniently, in PlayList you also always have access to the last node through its tail_ptr_private data member. As you write this function makes sure you add correctly when the PlayList is empty as well. Test both cases, and make sure both and

bool add(const Song& new_song) override;

5. Another thing that bothers you about your current implementation of PlayList is that removing a Song does not retain the order in which you added Songs to your PlayList. So you will override remove() to preserve the order of the Songs. To do this, you will implement your own private member function getPointerTowhich will return a pointer to the item you want to delete. This function will also have a reference parameter previous_ptr which will be set to point to the node preceding the one you want to remove. This will be useful to retain the order in the chain. So remove will call getPointerTo and using both pointers it will be able to delete a node while preserving the order and keeping the chain connected. Keep in mind that remove is public while getPointerTo is private (a helper function)

bool remove(const Song& a_song) override;

// post: previous_ptr is null if target is not in PlayList or if target is the

// first node, otherwise it points to the node preceding target

// return: either a pointer to the node containing target

// or the null pointer if the target is not in the PlayList.

Node* getPointerTo(const Song& target, Node*& previous_ptr) const;

6. Another typical thing to do with PlayLists is to play them in a loop. Well, you now have both a pointer to the first node and a pointer to the last node. It is thus trivial to write a loop() and an unloop() method for your PlayList. Note: all you are doing here is looping and unlooping the chain, "playing the songs" is clearly not a concern for this project.

void loop(); void unloop();

7. Finally, you still want to display the songs in your PlayList. Just as in your previous implementation, you will take advantage of the toVectormember inherited from LinkedSet to display the contents of the PlayList with the same format as in your previous implementation.

void displayPlayList();

Usage:

Make sure your code compiles and runs correctly with the main() function:

The task:

For this project you will use the same class interface SetInterface.h that LinkedSet inherits from. You are also give the Node class and the LinkedSet class (Node.h, Node.cpp, LinkedSet.h and LinkedSet.cpp). You are also given as a sample usage main() function. This is the function that will be used to test your code. You need to write and submit only the PlayList class (2 files: PlayList.h and PlayList.cpp).

Here are the codes for the following files.

LinkedSet.h

#ifndef LINKED_SET_ #define LINKED_SET_

#include "SetInterface.h" #include "Node.h"

template class LinkedSet : public SetInterface { protected: Node* head_ptr_; // Pointer to first node int item_count_; // Current count of set items // Returns either a pointer to the node containing a target // or the null pointer if the target is not in the set. Node* getPointerTo(const ItemType& target) const; public: LinkedSet(); // Default constructor LinkedSet(const LinkedSet& a_set); // Copy constructor virtual ~LinkedSet(); // Destructor should be virtual 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; std::vector toVector() const; }; // end LinkedSet

#include "LinkedSet.cpp" #endif /*LINKED_SET_*/

LinkedSet.cpp

#include "LinkedSet.h"

#include "Node.h"

//#include

#include

template

LinkedSet::LinkedSet() : head_ptr_(nullptr), item_count_(0)

{

} // end default constructor

template

LinkedSet::LinkedSet(const LinkedSet& a_set)

{

item_count_ = a_set.item_count_;

Node* orig_chain_ptr = a_set.head_ptr_; // Points to nodes in original chain

if (orig_chain_ptr == nullptr)

head_ptr_ = nullptr; // Original Set is empty

else

{

// Copy first node

head_ptr_ = new Node();

head_ptr_->setItem(orig_chain_ptr->getItem());

// Copy remaining nodes

Node* new_chain_ptr = head_ptr_; // Points to last node in new chain

orig_chain_ptr = orig_chain_ptr->getNext(); // Advance original-chain pointer

while (orig_chain_ptr != nullptr)

{

// Get next item from original chain

ItemType nextItem = orig_chain_ptr->getItem();

// Create a new node containing the next item

Node* new_node_ptr = new Node(nextItem);

// Link new node to end of new chain

new_chain_ptr->setNext(new_node_ptr);

// Advance pointer to new last node

new_chain_ptr = new_chain_ptr->getNext();

// Advance original-chain pointer

orig_chain_ptr = orig_chain_ptr->getNext();

} // end while

new_chain_ptr->setNext(nullptr); // Flag end of chain

} // end if

} // end copy constructor

template

LinkedSet::~LinkedSet()

{

clear();

} // end destructor

template

bool LinkedSet::isEmpty() const

{

return item_count_ == 0;

} // end isEmpty

template

int LinkedSet::getCurrentSize() const

{

return item_count_;

} // end getCurrentSize

template

bool LinkedSet::add(const ItemType& new_entry)

{

if(!contains(new_entry))

{

// Add to beginning of chain: new node references rest of chain;

// (head_ptr_ is null if chain is empty)

Node* next_node_ptr = new Node();

next_node_ptr->setItem(new_entry);

next_node_ptr->setNext(head_ptr_); // New node points to chain

head_ptr_ = next_node_ptr; // New node is now first node

item_count_++;

return true;

}else

return false;

} // end add

template

std::vector LinkedSet::toVector() const

{

std::vector set_contents;

Node* cur_ptr = head_ptr_;

int counter = 0;

while ((cur_ptr != nullptr) && (counter < item_count_))

{

set_contents.push_back(cur_ptr->getItem());

cur_ptr = cur_ptr->getNext();

counter++;

} // end while

return set_contents;

} // end toVector

template

bool LinkedSet::remove(const ItemType& an_entry)

{

Node* entry_node_ptr = getPointerTo(an_entry);

bool can_remove_item = !isEmpty() && (entry_node_ptr != nullptr);

if (can_remove_item)

{

// Copy data from first node to located node

entry_node_ptr->setItem(head_ptr_->getItem());

// Delete first node

Node* node_to_delete_ptr = head_ptr_;

head_ptr_ = head_ptr_->getNext();

// Return node to the system

node_to_delete_ptr->setNext(nullptr);

delete node_to_delete_ptr;

node_to_delete_ptr = nullptr;

item_count_--;

} // end if

return can_remove_item;

} // end remove

template

void LinkedSet::clear()

{

Node* node_to_delete_ptr = head_ptr_;

while (head_ptr_ != nullptr)

{

head_ptr_ = head_ptr_->getNext();

// Return node to the system

node_to_delete_ptr->setNext(nullptr);

delete node_to_delete_ptr;

node_to_delete_ptr = head_ptr_;

} // end while

// head_ptr_ is nullptr; nodeToDeletePtr is nullptr

item_count_ = 0;

} // end clear

template

bool LinkedSet::contains(const ItemType& anEntry) const

{

return (getPointerTo(anEntry) != nullptr);

} // end contains

// private

// Returns either a pointer to the node containing a given entry

// or the null pointer if the entry is not in the set.

template

Node* LinkedSet::getPointerTo(const ItemType& an_entry) const

{

bool found = false;

Node* cur_ptr = head_ptr_;

while (!found && (cur_ptr != nullptr))

{

if (an_entry == cur_ptr->getItem())

found = true;

else

cur_ptr = cur_ptr->getNext();

} // end while

return cur_ptr;

} // end getPointerTo

SetInterface.h

#ifndef SET_INTERFACE_ #define SET_INTERFACE_

#include

template class SetInterface { public: /** Gets the current number of entries in this set. @return The integer number of entries currently in the set. */ virtual int getCurrentSize() const = 0; /** Sees whether this set is empty. @return True if the set is empty, or false if not. */ virtual bool isEmpty() const = 0; /** Adds a new entry to this set. @post If successful, newEntry is stored in the set and the count of items in the set has increased by 1. @param newEntry The object to be added 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 set, if possible. @post If successful, anEntry has been removed from the set and the count of items in the set 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 set. @post set contains no items, and the count of items is 0. */ virtual void clear() = 0; /** Tests whether this set contains a given entry. @param anEntry The entry to locate. @return True if set contains anEntry, or false otherwise. */ virtual bool contains(const ItemType& anEntry) const = 0; /** Fills a vector with all entries that are in this set. @return A vector containing all the entries in the set. */ virtual std::vector toVector() const = 0; /** Destroys object and frees memory allocated by object. (See C++ Interlude 2) */ virtual ~SetInterface () { } }; // end SetfInterface #endif

Node.h

#ifndef NODE_ #define NODE_

template class Node { private: ItemType item_; // A data item Node* next_; // Pointer to next node public: Node(); //default constructor Node(const ItemType& an_item); //parameterized constructor Node(const ItemType& an_item, Node* next_node_ptr);//parameterized constructor //post: gives a value to the data member void setItem(const ItemType& an_item); //post: gives a value to the pointer member void setNext(Node* next_node_ptr);

//return: the data member ItemType getItem() const ; //return: the pointer to the next node Node* getNext() const ; }; // end Node

#include "Node.cpp" #endif

Node.cpp

template Node::Node() : next_(nullptr) { } // end default constructor

template Node::Node(const ItemType& an_item) : item_(an_item), next_(nullptr) { } // end constructor

template Node::Node(const ItemType& an_item, Node* next_node_ptr) : item_(an_item), next_(next_node_ptr) { } // end constructor

template void Node::setItem(const ItemType& an_item) { item_ = an_item; } // end setItem

template void Node::setNext(Node* next_node_ptr) { next_ = next_node_ptr; } // end setNext

template ItemType Node::getItem() const { return item_; } // end getItem

template Node* Node::getNext() const { return next_; } // end getNext

Song.cpp

#include "Song.h" #include

Song::Song():author_(""), album_(""){ }

Song::Song(const string& title, const string& author, const string& album){

title_ = title;

author_ = author;

album_ = album;

}

void Song::setTitle(string title){ //"set" in setTitle here means "give a value" and has nothing

title_ = title ;

}

void Song::setAuthor(string author){

author_ = author;

}

void Song::setAlbum(string album){

album_ = album;

}

string Song::getTitle() const{

return title_;

}

string Song::getAuthor() const{

return author_;

}

string Song::getAlbum() const{

return album_;

}

bool operator==(const Song& lhs, const Song& rhs){

if(lhs.getTitle()==rhs.getTitle() && lhs.getAlbum()==rhs.getAlbum() && lhs.getAuthor()==rhs.getAuthor()){

return true;

}

return false;

}

Song.h

#ifndef SONG_H_ #define SONG_H_

#include #include "SetInterface.h"

using namespace std;

class Song{ private: std::string title_; //title of the Song std::string author_; //name of the author std::string album_; //name of the album

public: Song(); //default constructor

Song(const std::string& title, const std::string& author = "", const std::string& album = ""); //paramterized constructor

//sets the title_ void setTitle(std::string title);

//sets the author_ void setAuthor(std::string author);

//sets the album_ void setAlbum(std::string album);

//returns the title_ std::string getTitle() const;

//return the author_ std::string getAuthor() const;

//return the album_ std::string getAlbum() const;

//parem: Songs information friend bool operator==(const Song& lhs, const Song& rhs);

};

#endif //end of class Song

main.cpp

int main() {

// Test PlayList

std::cout << "**** Instantiating Song objects **** ";

Song song1("song1","author1","album1");

Song song2("song2", "author2", "album2");

Song song3("song3", "author3", "album3");

Song song4("song4", "author4", "album4");

Song song5("song5", "author5", "album5");

std::cout << " **** Testing PlayList class **** ";

std::cout << " Add songs to PlayList, check adding to end of chain and no duplicates allowed: ";

PlayList playlist1(song1);

playlist1.add(song2);

playlist1.add(song3);

playlist1.add(song1);

playlist1.add(song2);

playlist1.add(song3);

std::vector song_vector = playlist1.toVector();

playlist1.displayPlayList();

std::cout << " Add remaining songs ";

playlist1.add(song4);

playlist1.add(song5);

playlist1.displayPlayList();

std::cout << " Check that linked chain corresponds in LinkedSet(true) ";

std::cout << playlist1.contains(song3); // (true)

std::cout << " Test removing songs from PlayList, check that order is preserved ";

std::cout << " Remove from the middle ";

playlist1.remove(song3);

playlist1.displayPlayList();

std::cout << " Remove first song ";

playlist1.remove(song1);

playlist1.displayPlayList();

std::cout << " Remove last song ";

playlist1.remove(song5);

playlist1.displayPlayList();

std::cout << " Check that linked chain corresponds in LinkedSet after removal (false) ";

std::cout << playlist1.contains(song3); //(false)

std::cout << " Test copy constructor ";

PlayList playlist2 = playlist1;

std::cout << " Printing playlist2 ";

playlist2.displayPlayList();

std::cout << " Check that copied chain corresponds in LinkedSet ";

std::cout << playlist2.contains(song2) << std::endl; // (true)

std::cout << playlist2.contains(song3) << std::endl; //(false)

std::cout << " Add song to copied playlist ";

playlist2.add(song1);

playlist2.displayPlayList();

std::cout << " Remove last song from copied playlist ";

playlist2.remove(song1);

playlist2.displayPlayList();

std::cout << " Remove first song from copied playlist ";

playlist2.remove(song2);

playlist2.displayPlayList();

return 0;

}

Output:

Running the above main() program should produce this output:

**** Instantiating Song objects ****

**** Testing PlayList class ****

Add songs to PlayList, check adding to end of chain and no duplicates allowed:

* Titile: song1* Author: author1* Album: album1 *

* Titile: song2* Author: author2* Album: album2 *

* Titile: song3* Author: author3* Album: album3 *

End of playlist

Add remaining songs

* Titile: song1* Author: author1* Album: album1 *

* Titile: song2* Author: author2* Album: album2 *

* Titile: song3* Author: author3* Album: album3 *

* Titile: song4* Author: author4* Album: album4 *

* Titile: song5* Author: author5* Album: album5 *

End of playlist

Check that linked chain corresponds in LinkedSet(true)

1

Test removing songs from PlayList, check that order is preserved

Remove from the middle

* Titile: song1* Author: author1* Album: album1 *

* Titile: song2* Author: author2* Album: album2 *

* Titile: song4* Author: author4* Album: album4 *

* Titile: song5* Author: author5* Album: album5 *

End of playlist

Remove first song

* Titile: song2* Author: author2* Album: album2 *

* Titile: song4* Author: author4* Album: album4 *

* Titile: song5* Author: author5* Album: album5 *

End of playlist

Remove last song

* Titile: song2* Author: author2* Album: album2 *

* Titile: song4* Author: author4* Album: album4 *

End of playlist

Check that linked chain corresponds in LinkedSet after removal (false)

0

Test copy constructor

Printing playlist2

* Titile: song2* Author: author2* Album: album2 *

* Titile: song4* Author: author4* Album: album4 *

End of playlist

Check that copied chain corresponds in LinkedSet

1

0

Add song to copied playlist

* Titile: song2* Author: author2* Album: album2 *

* Titile: song4* Author: author4* Album: album4 *

* Titile: song1* Author: author1* Album: album1 *

End of playlist

Remove last song from copied playlist

* Titile: song2* Author: author2* Album: album2 *

* Titile: song4* Author: author4* Album: album4 *

End of playlist

Remove first song from copied playlist

* Titile: song4* Author: author4* Album: album4 *

End of playlist

Program ended with exit code: 0

Please do not change any of this code. leave this as it is. but please write playlist.cpp and playlist.h

Thank you for your help.

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Machine Learning And Knowledge Discovery In Databases European Conference Ecml Pkdd 2015 Porto Portugal September 7 11 2015 Proceedings Part 1 Lnai 9284

Authors: Annalisa Appice ,Pedro Pereira Rodrigues ,Vitor Santos Costa ,Carlos Soares ,Joao Gama ,Alipio Jorge

1st Edition

3319235273, 978-3319235271

More Books

Students also viewed these Databases questions

Question

Evaluate employees readiness for training. page 275

Answered: 1 week ago