Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Given LinkedSet.cpp , Node.cpp and Playlist.h........Do Playlist.cpp LinkedSet.cpp-________________________ template LinkedSet ::LinkedSet() : head_ptr_(nullptr), item_count_(0) { } // end default constructor template LinkedSet ::LinkedSet(const LinkedSet &

Given LinkedSet.cpp , Node.cpp and Playlist.h........Do Playlist.cpp

LinkedSet.cpp-________________________

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

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

Playlist.h________________

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

The LinkedSet copy constructor is called first, making a deep copy of the chain. LinkedSet,however, will only take care of copying the base-class data members.

PlayList's copy constructor will 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 function getPointerToLastNode 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 head_ptr_ and tail_ptr point to the correct node at the end of this operation.

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 getPointerTo which 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 toVector member inherited from LinkedSet to display the contents of the PlayList with the same format as in your previous implementation.

void displayPlayList();

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

Beginning ASP.NET 4.5 Databases

Authors: Sandeep Chanda, Damien Foggon

3rd Edition

1430243805, 978-1430243809

More Books

Students also viewed these Databases questions