Question
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
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