Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

/**** [10 points] The Bag_T class has two identical methods to release cats or d

ID: 644996 • Letter: #

Question

/****

[10 points]

The Bag_T class has two identical methods to release cats or dogs from the bag. The only difference is the data type of the released pets, Cat_T or Dog_T, and thus it is a good candidate for a templated function. Write the implementation of such template function, parametised with a generic type called <PetType_T>. Please note the the logic is identical to releaseCats or releaseDogs. The only difference is a generic type.

o      The code for a template function must live in the .h file, not the .cpp file. No definition is needed. This is because such parametized code has to be pre-processed before it can be compiled.

*/

//Interface File for Pets

#ifndef PETS_H

#define PETS_H

#include <iostream>

#include <string>

#include <vector>

namespace csc161

{

       class Pet_T

       {

       public:

                                       

             // Counting on a default constructor

             Pet_T(string p_name);

             // Constructor sets name

             // Destructor

             ~Pet_T();          

                          

             // Accessors and Mutators

             void setName(string p_name);

             string getName() const;

             // Pet introduces himself. Only concrete derived classes implement it

             void virtual whoAmI() const;

            

             //Overloads the >> operator for input values of type Pet_T. Optional           

             friend istream& operator >>(istream& ins, Pet_T& the_object);

                    //Precondition: If ins is a file input stream, then ins has already been

                    //connected to a file.

             //Overloads the << operator for output values of type Pet_T.

             friend ostream& operator <<(ostream& outs, const Pet_T& the_object);

                    //Precondition: If outs is a file output stream, then outs has already been

                    //connected to a file.

      

       protected:

             string name;

       };

      

       // Use 'typedef' to define a new type called PetPtr which is a pointer to Pet_T

       typedef Pet_T* PetPtr;

       class Cat_T : public Pet_T {

             public:

                    // Constructor sets name

                    Cat_T(string p_name);

                   

                    // Pet introduces himself: "My name is <name>. I am a cat."

                    void virtual whoAmI() const override;

                    /////////////////////////// EXAM TASK

                    // Declare a void function hairBall();

       };

       class Dog_T : public Pet_T {

             public:

                    // Constructor sets name

                    Dog_T(string p_name);

                    // Pet introduces himself: "My name is <name>. I am a dog."

                    void virtual whoAmI() const override;

                    /////////////////////////// EXAM TASK

                    // Declare a void function squirell()

                   

       };

       // EXAM TASK

       // Add Frog_T class declaration

      

       class Bag_T {

       public:

             // Not declaring a default constructor, the system will do that

             // Contructor to sets size of Bag

             Bag_T(unsigned p_capacity);

             // Copy bag

             Bag_T(const Bag_T& p_bag);

             // Destructor

             ~Bag_T();

             size_t getCapacity() const;

             size_t getSize() const;

             // Adds Pet to Bag

             void addPet(PetPtr p_pet);

                          

             // Release Cats

             void releaseCats();

             // Release Dogs

             void releaseDogs();

             /////////////////////////////// EXAM TASK

             // Template function to release pets, parametized on type of pet

            

             template<typename PetType_T> void releasePets() {

                   

             };

            

             // Print content of Bag

             void petsInBag();

             friend ostream& operator <<(ostream& outs, const Bag_T& the_object);

             //Overloads the << operator for output content of type Bag_T.

             //Precondition: If outs is a file output stream, then outs has already been

             //connected to a file.

       private:

             vector<PetPtr> pets;

       };

} // namespace csc161

#endif //PETS_H

//Implementation File for Pets.cpp

//Header file is in Pets.h

using namespace std;

#include <iostream>

#include <string>

#include "PetsInBag.h"

namespace csc161

{

            

       // Contructor to sets name

       Pet_T::Pet_T(string p_name) {

             name = p_name;     

       };

      

       //Pet_T::Pet_T() {};

            

       // Destructor

       Pet_T::~Pet_T() {};

      

       void Pet_T::setName(string p_name) {

             name = p_name;

       }

            

       string Pet_T::getName() const {

             return name;

       }

            

       void Pet_T::whoAmI() const {};

      

       istream& operator >>(istream& ins, Pet_T& the_object)

             //Overloads the >> operator for input values of type Pet_T.

             //Precondition: If ins is a file input stream, then ins has already been

             //connected to a file.

       {

             {

                    cout << "Enter Pet's Name: ";

                    ins >> the_object.name;

                    return ins;

             }

       };

       ostream& operator <<(ostream& outs, const Pet_T& the_object)

       //Overloads the << operator for output values of type Pet_T.

       //Precondition: If outs is a file output stream, then outs has already been

       //connected to a file.

       {           

             the_object.whoAmI();

             outs << endl;

           return outs;          

       }

       // Cat_T implementation

       Cat_T::Cat_T(string p_name) : Pet_T(p_name) {};

      

       void Cat_T::whoAmI() const {

             cout << "My name is " << name << ". I am a cat." << endl;

       }

       // Hair Ball!

       void Cat_T::hairBall() {

             /////////////////////////// EXAM TASK

             // Cat says: "Hair ball!"

       }

       // Dog_T implementation

       Dog_T::Dog_T(string p_name) : Pet_T(p_name) { };

       void Dog_T::whoAmI() const {           

             cout << "My name is " << name << ". I am a dog." << endl;

       }

       void Dog_T::squirrel() {

             ///////////////////////// EXAM TASK

             // Dog says "Squirrel!"

            

       }

       ///////////////////////////// EXAM TASK

       // Add Frog_T class implementation

      

       ///////////// Bag Implementation

       // Contructor to sets size of Bag

       Bag_T::Bag_T(unsigned p_capacity) {

             pets.reserve(p_capacity);

       };

       // Returns bag's capacity

       size_t Bag_T::getCapacity() const {

             ///////////////////////// EXAM TASK

             // Return bag capacity

       }

       // Returns bag's size

       size_t Bag_T::getSize() const {

            

             /////////////////////////// EXAM TASK

             // Return bag size

       }

       // Copy constructor: copies content of p_bag to a newly constructed bag

       Bag_T::Bag_T(const Bag_T& p_bag) {

             // Allocate new bag

             pets.reserve(p_bag.getCapacity());            

             // Copy each pet

             for (unsigned i = 0; i < p_bag.getSize(); i++) {

                   

                    ////////////////////////////////// EXAM TASK

                    // It could also be a Frog_T

                    Cat_T* catPointer = NULL;

                    Dog_T* dogPointer = NULL;

                   

                    // To find whether basePointer is pointing to Derived type of object

                    // Runtime Type Identification (RTTI)

                    /////////////////////////////////// EXAM TASK

                    // It could also be a Frog_T

                    catPointer = dynamic_cast<Cat_T*>(p_bag.pets[i]);

                    dogPointer = dynamic_cast<Dog_T*>(p_bag.pets[i]);

                   

                    if (catPointer != NULL) // Copies cat

                    {                         

                           pets.push_back(new Cat_T(*catPointer));

                    }

                    else

                    if (dogPointer != NULL) // Copies dog

                    {                         

                           pets.push_back(new Dog_T(*dogPointer));

                    }

                   

                    ///////////////////////////////// EXAM TASK

                    // It could also be a Frog_T

             }

       }

       // Destructor

       Bag_T::~Bag_T() {

             for(int i = 0; i < pets.size(); i++) {

                    delete pets[i];

             }

       };

      

       // Adds Pet to Bag

       void Bag_T::addPet(PetPtr p_pet) {

             if (pets.size() < pets.capacity())

                    pets.push_back(p_pet);

             else

                    cout << "Bag is full" << endl;         

       }

            

       // Release Cats

       void Bag_T::releaseCats() {

             Cat_T* catPointer = NULL;

             for (unsigned i = 0; i < pets.size(); i++)

             {                  

                    // To find whether base pointer is pointing to derived type of object

                    // Runtime Type Identification (RTTI)

                    catPointer = dynamic_cast<Cat_T*>(pets[i]);

                    if (catPointer != NULL) // It is a Cat!

                    {

                           //////////////////////////////// EXAM TASK

                           // As a cat gets released, it says "Hair Ball!"

                           // Now release that cat

                           delete pets[i];

                           pets.erase(pets.begin() + i);

                           i--;

                    }

             }

       }

       // Release Dogs

         void Bag_T::releaseDogs() {

                 Dog_T* dogPointer = NULL;

                 for (unsigned i = 0; i < pets.size(); i++)

                 {

                          // To find whether base pointer is pointing to derived type of object

                          // Runtime Type Identification (RTTI)

                          dogPointer = dynamic_cast<Dog_T*>(pets[i]);

                          if (dogPointer != NULL) // It is a dog!

                          {

                                  //////////////////////// EXAM TASK

                                  // As a dog gets released, it says "Squirrel!"

                                  // Now release that dog

                                  delete pets[i];

                                  pets.erase(pets.begin() + i);

                                  i--;

                          }

                 }

         }

                

         ostream& operator <<(ostream& outs, const Bag_T& the_object)

                 //Overloads the << operator for output values of type Bag_T.

                 //Precondition: If outs is a file output stream, then outs has already been

                 //connected to a file.

         {

                 ///////////////////////////////// EXAM TASK

                 // Check if bag is empty, and if so print "The bag is empty"

                

                 // Print bag content

                 for (unsigned i = 0; i < the_object.pets.size(); i++) {

                          outs << *(the_object.pets[i]);

                 };

                

                 return outs;

         }

} // namespace csc161

// *********************************************************************

// This program models a bag with pets to demonstrate polymorphism

// It holds a vector of pointers to a generic Pet, but specific pets are added

// *********************************************************************

#include <iostream>

#include <cstdlib>

#include <string>

using namespace std;

#include "PetsInBag.h"

using namespace csc161;

///////////////////// FUNCTIONS PROTOTYPES

// Utility function to enter Pet's name

void enterName(string& p_name);

///////////////////// FUNCTIONS IMLEMENTATION

void enterName(string& p_name){

         cout << "Enter Pet's Name: ";

         cin >> p_name;

}

// ======================

//     main function

// ======================

int main()

{

         Bag_T bag(10); // Instantiates a Bag_T

        

         string pet_name; // Variable to enter pet's name

         int choice = -1;

         // Main Menu

         while (choice != 0)

         {

                 cout << endl;

                

                 cout << "MAIN MENU" << endl;

                 cout << "0) Quit" << endl;

                 cout << "1) Add Cat" << endl;

                 cout << "2) Add Dog" << endl;

        ////////////////// EXAM TASK

                 cout << "4) Print Bag" << endl;

                 cout << "5) Release Cats" << endl;

                 cout << "6) Release Dogs" << endl;

                 cin >> choice;

                 switch (choice) {

                 case 1:

                          enterName(pet_name);                      

                          bag.addPet(new Cat_T(pet_name)); // Polymorphism: addPet is defined to add generic Pet_T, but passes in Cat_T

                          break;

                 case 2:

                          enterName(pet_name);

                          bag.addPet(new Dog_T(pet_name)); // Polymorphism: addPet is defined to add generic Pet_T, but passes in Dog_T

                          break;

             ////////////////// EXAM TASK

                 case 4:

                          cout << bag; // Prints content of Bag

                          break;

                 case 5:

                          bag.releaseCats();

                          break;

                 case 6:

                          bag.releaseDogs();

                          break;

                 default:

                          break;

                 };              

         }

         // To demo the copy constructor

         Bag_T new_bag = Bag_T(bag);

         cout << new_bag;

         system("pause");

         return 0;

}

Explanation / Answer

#ifndef PETS_H

#define PETS_H

#include <iostream>

#include <string>

#include <vector>

namespace csc161

{

       class Pet_T

       {

       public:

                                     

             // Counting on a default constructor

             Pet_T(string p_name);

             // Constructor sets name

             // Destructor

             ~Pet_T();        

                        

             // Accessors and Mutators

             void setName(string p_name);

             string getName() const;

             // Pet introduces himself. Only concrete derived classes implement it

             void virtual whoAmI() const;

          

             //Overloads the >> operator for input values of type Pet_T. Optional         

             friend istream& operator >>(istream& ins, Pet_T& the_object);

                    //Precondition: If ins is a file input stream, then ins has already been

                    //connected to a file.

             //Overloads the << operator for output values of type Pet_T.

             friend ostream& operator <<(ostream& outs, const Pet_T& the_object);

                    //Precondition: If outs is a file output stream, then outs has already been

                    //connected to a file.

    

       protected:

             string name;

       };

    

       // Use 'typedef' to define a new type called PetPtr which is a pointer to Pet_T

       typedef Pet_T* PetPtr;

       class Cat_T : public Pet_T {

             public:

                    // Constructor sets name

                    Cat_T(string p_name);

                 

                    // Pet introduces himself: "My name is <name>. I am a cat."

                    void virtual whoAmI() const override;

                    /////////////////////////// EXAM TASK

                    // Declare a void function hairBall();

       };

       class Dog_T : public Pet_T {

             public:

                    // Constructor sets name

                    Dog_T(string p_name);

                    // Pet introduces himself: "My name is <name>. I am a dog."

                    void virtual whoAmI() const override;

                    /////////////////////////// EXAM TASK

                    // Declare a void function squirell()

                 

       };

       // EXAM TASK

       // Add Frog_T class declaration

    

       class Bag_T {

         public:

               // Not declaring a default constructor, the system will do that

               // Contructor to sets size of Bag

               Bag_T(unsigned p_capacity);

               // Copy bag

               Bag_T(const Bag_T& p_bag);

               // Destructor

               ~Bag_T();

               size_t getCapacity() const;

               size_t getSize() const;

               // Adds Pet to Bag

               void addPet(PetPtr p_pet);

                          

               // Release Cats

               void releaseCats();

               // Release Dogs

               void releaseDogs();

               /////////////////////////////// EXAM TASK

               // Template function to release pets, parametized on type of pet

            

               template<typename PetType_T> void releasePets() {

                   

               };

            

               // Print content of Bag

               void petsInBag();

               friend ostream& operator <<(ostream& outs, const Bag_T& the_object);

               //Overloads the << operator for output content of type Bag_T.

               //Precondition: If outs is a file output stream, then outs has already been

               //connected to a file.

       private:

             vector<PetPtr> pets;

       };

} // namespace csc161

#endif //PETS_H

//Implementation File for Pets.cpp

//Header file is in Pets.h

using namespace std;

#include <iostream>

#include <string>

#include "PetsInBag.h"

namespace csc161

{

          

       // Contructor to sets name

       Pet_T::Pet_T(string p_name) {

             name = p_name;   

       };

    

       //Pet_T::Pet_T() {};

          

       // Destructor

       Pet_T::~Pet_T() {};

    

       void Pet_T::setName(string p_name) {

             name = p_name;

       }

          

       string Pet_T::getName() const {

             return name;

       }

          

       void Pet_T::whoAmI() const {};

    

       istream& operator >>(istream& ins, Pet_T& the_object)

             //Overloads the >> operator for input values of type Pet_T.

             //Precondition: If ins is a file input stream, then ins has already been

             //connected to a file.

       {

             {

                    cout << "Enter Pet's Name: ";

                    ins >> the_object.name;

                    return ins;

             }

       };

       ostream& operator <<(ostream& outs, const Pet_T& the_object)

       //Overloads the << operator for output values of type Pet_T.

       //Precondition: If outs is a file output stream, then outs has already been

       //connected to a file.

       {         

             the_object.whoAmI();

             outs << endl;

           return outs;        

       }

       // Cat_T implementation

       Cat_T::Cat_T(string p_name) : Pet_T(p_name) {};

    

       void Cat_T::whoAmI() const {

             cout << "My name is " << name << ". I am a cat." << endl;

       }

       // Hair Ball!

       void Cat_T::hairBall() {

             /////////////////////////// EXAM TASK

             // Cat says: "Hair ball!"

       }

       // Dog_T implementation

       Dog_T::Dog_T(string p_name) : Pet_T(p_name) { };

       void Dog_T::whoAmI() const {         

             cout << "My name is " << name << ". I am a dog." << endl;

       }

       void Dog_T::squirrel() {

             ///////////////////////// EXAM TASK

             // Dog says "Squirrel!"

          

       }

       ///////////////////////////// EXAM TASK

       // Add Frog_T class implementation

    

       ///////////// Bag Implementation

       // Contructor to sets size of Bag

       Bag_T::Bag_T(unsigned p_capacity) {

             pets.reserve(p_capacity);

       };

       // Returns bag's capacity

       size_t Bag_T::getCapacity() const {

             ///////////////////////// EXAM TASK

             // Return bag capacity

       }

       // Returns bag's size

       size_t Bag_T::getSize() const {

          

             /////////////////////////// EXAM TASK

             // Return bag size

       }

       // Copy constructor: copies content of p_bag to a newly constructed bag

       Bag_T::Bag_T(const Bag_T& p_bag) {

             // Allocate new bag

             pets.reserve(p_bag.getCapacity());          

             // Copy each pet

             for (unsigned i = 0; i < p_bag.getSize(); i++) {

                 

                    ////////////////////////////////// EXAM TASK

                    // It could also be a Frog_T

                    Cat_T* catPointer = NULL;

                    Dog_T* dogPointer = NULL;

                 

                    // To find whether basePointer is pointing to Derived type of object

                    // Runtime Type Identification (RTTI)

                    /////////////////////////////////// EXAM TASK

                    // It could also be a Frog_T

                    catPointer = dynamic_cast<Cat_T*>(p_bag.pets[i]);

                    dogPointer = dynamic_cast<Dog_T*>(p_bag.pets[i]);

                 

                    if (catPointer != NULL) // Copies cat

                    {                       

                           pets.push_back(new Cat_T(*catPointer));

                    }

                    else

                    if (dogPointer != NULL) // Copies dog

                    {                       

                           pets.push_back(new Dog_T(*dogPointer));

                    }

                 

                    ///////////////////////////////// EXAM TASK

                    // It could also be a Frog_T

             }

       }

       // Destructor

       Bag_T::~Bag_T() {

             for(int i = 0; i < pets.size(); i++) {

                    delete pets[i];

             }

       };

    

       // Adds Pet to Bag

       void Bag_T::addPet(PetPtr p_pet) {

             if (pets.size() < pets.capacity())

                    pets.push_back(p_pet);

             else

                    cout << "Bag is full" << endl;       

       }

          

       // Release Cats

       void Bag_T::releaseCats() {

             Cat_T* catPointer = NULL;

             for (unsigned i = 0; i < pets.size(); i++)

             {                

                    // To find whether base pointer is pointing to derived type of object

                    // Runtime Type Identification (RTTI)

                    catPointer = dynamic_cast<Cat_T*>(pets[i]);

                    if (catPointer != NULL) // It is a Cat!

                    {

                           //////////////////////////////// EXAM TASK

                           // As a cat gets released, it says "Hair Ball!"

                           // Now release that cat

                           delete pets[i];

                           pets.erase(pets.begin() + i);

                           i--;

                    }

             }

       }

       // Release Dogs

         void Bag_T::releaseDogs() {

                 Dog_T* dogPointer = NULL;

                 for (unsigned i = 0; i < pets.size(); i++)

                 {

                          // To find whether base pointer is pointing to derived type of object

                          // Runtime Type Identification (RTTI)

                          dogPointer = dynamic_cast<Dog_T*>(pets[i]);

                          if (dogPointer != NULL) // It is a dog!

                          {

                                  //////////////////////// EXAM TASK

                                  // As a dog gets released, it says "Squirrel!"

                                  // Now release that dog

                                  delete pets[i];

                                  pets.erase(pets.begin() + i);

                                  i--;

                          }

                 }

         }

              

         ostream& operator <<(ostream& outs, const Bag_T& the_object)

                 //Overloads the << operator for output values of type Bag_T.

                 //Precondition: If outs is a file output stream, then outs has already been

                 //connected to a file.

         {

                 ///////////////////////////////// EXAM TASK

                 // Check if bag is empty, and if so print "The bag is empty"

              

                 // Print bag content

                 for (unsigned i = 0; i < the_object.pets.size(); i++) {

                          outs << *(the_object.pets[i]);

                 };

              

                 return outs;

         }

} // namespace csc161

// *********************************************************************

// This program models a bag with pets to demonstrate polymorphism

// It holds a vector of pointers to a generic Pet, but specific pets are added

// *********************************************************************

#include <iostream>

#include <cstdlib>

#include <string>

using namespace std;

#include "PetsInBag.h"

using namespace csc161;

///////////////////// FUNCTIONS PROTOTYPES

// Utility function to enter Pet's name

void enterName(string& p_name);

///////////////////// FUNCTIONS IMLEMENTATION

void enterName(string& p_name){

         cout << "Enter Pet's Name: ";

         cin >> p_name;

}

// ======================

//     main function

// ======================

int main()

{

         Bag_T bag(10); // Instantiates a Bag_T

      

         string pet_name; // Variable to enter pet's name

         int choice = -1;

         // Main Menu

         while (choice != 0)

         {

                 cout << endl;

              

                 cout << "MAIN MENU" << endl;

                 cout << "0) Quit" << endl;

                 cout << "1) Add Cat" << endl;

                 cout << "2) Add Dog" << endl;

        ////////////////// EXAM TASK

                 cout << "4) Print Bag" << endl;

                 cout << "5) Release Cats" << endl;

                 cout << "6) Release Dogs" << endl;

                 cin >> choice;

                 switch (choice) {

                 case 1:

                          enterName(pet_name);                    

                          bag.addPet(new Cat_T(pet_name)); // Polymorphism: addPet is defined to add generic Pet_T, but passes in Cat_T

                          break;

                 case 2:

                          enterName(pet_name);

                          bag.addPet(new Dog_T(pet_name)); // Polymorphism: addPet is defined to add generic Pet_T, but passes in Dog_T

                          break;

             ////////////////// EXAM TASK

                 case 4:

                          cout << bag; // Prints content of Bag

                          break;

                 case 5:

                          bag.releaseCats();

                          break;

                 case 6:

                          bag.releaseDogs();

                          break;

                 default:

                          break;

                 };            

         }

         // To demo the copy constructor

         //Bag_T new_bag = Bag_T(bag);//remove this line

         cout << new_bag;

         system("pause");

         return 0;

}