Task •class Creature will be the parent class for the other classes. An Animal and a Hunter are both Creatures, so both
Posted: Sun May 15, 2022 8:22 am
Task
•class Creature will be the parent class for the other classes.
An Animal and a Hunter are both Creatures, so both
of these classes will extend Creature. A Wolf is both an Animal and
a Hunter, so it will extend both Animal and
Hunter (multiple inheritance).
•Class Pack will represent a collection of Creatures. It has an
internal pointer called members that refers to an array
of pointers to Creature objects. Near the top of file Pack.hpp we
use type aliasing to give the type Creature* the
additional name of CreaturePtr (this is done for convenience). This
allows us to write CreaturePtr in place of
Creature
•Take a look at the source code. Your task is to follow the
instructions given in the comments that start with TODO.
Make sure to add more testing code to main.cpp.
Main.cpp
#include
#include
#include "Wolf.hpp"
#include "Pack.hpp"
using namespace std;
// print strengths of all members in a Pack
void printStrengths(const Pack & p);
// deletes all members of a Pack
void deleteMembers(Pack & p);
int main()
{
Creature * c = new Wolf(25, 12);
cout << "c->size(): " << c->getSize() <<
endl; // 25
cout << "c->strength(): " << c->strength()
<< endl; // 31
Pack p1{3};
p1[0] = new Wolf(26, 13);
p1[1] = new Hunter(20.7, 14.6);
p1[2] = new Animal(29);
cout << "p1 strengths: ";
printStrengths(p1); // 32.5 35.3 29
try
{
p1[3] = nullptr;
cout << "(1) Error: Pack::operator[] did not throw an
out_of_range "
"exception as expected." << endl;
}
catch (const out_of_range & e)
{
cout << "(1) Pack::operator[] correctly throw an out_of_range
exception"
<< endl;
}
try
{
cout << p1[3]->strength() << endl;
cout << "(2) Error: Pack::operator[] did not throw an
out_of_range "
"exception as expected." << endl;
}
catch (const out_of_range & e)
{
cout << "(2) Pack::operator[] correctly throw an out_of_range
exception"
<< endl;
}
Pack p2{8};
p2[0] = new Wolf(24, 16);
p2[1] = new Wolf(23, 17);
p2[2] = new Animal(30.2);
p2[3] = new Hunter(21, 19);
p2[4] = new Wolf(20.4, 19.7);
p2[5] = new Wolf();
p2[6] = new Hunter();
p2[7] = new Animal();
cout << "p2 strengths: ";
printStrengths(p2); // 32 31.5 30.2 40 30.25 1.5 2 1
cout << "p3 = p1 + p2" << endl;
Pack p3 = p1 + p2;
cout << "p3 strengths: ";
printStrengths(p3); // 32.5 35.3 29 32 31.5 30.2 40 30.25 1.5 2
1
// TODO: add more testing code here.
// Make sure your code does not have a memory leak
// (every call to new must have a corresponding call to
delete).
// delete dynamically allocated data
deleteMembers(p1);
deleteMembers(p2);
delete c;
}
void printStrengths(const Pack & p)
{
for (unsigned int i=0; i < p.size(); i++)
{
if (i != 0) cout << " ";
cout << p->strength();
}
cout << endl;
}
void deleteMembers(Pack & p)
{
for (unsigned int i=0; i < p.size(); i++)
{
delete p;
p = nullptr;
}
}
Pack.hpp
#ifndef PACK_HPP
#define PACK_HPP
#include "Creature.hpp"
// Type alias for a pointer to a Creature.
// CreaturePtr is the same as writing Creature*
using CreaturePtr = Creature*;
class Pack
{
private:
unsigned int mySize; // number of elements in array members
CreaturePtr * members; // array of pointers to Creatures
public:
explicit Pack(unsigned int theSize);
Pack(const Pack & other); // copy constructor
Pack(Pack && other); // move constructor
~Pack(); // destructor
unsigned int size() const {return mySize;}
Pack & operator=(const Pack & rhs); // copy
assignment
Pack & operator=(Pack && rhs); // move assignment
// overload both versions of operator[]
const CreaturePtr & operator[](unsigned int index) const;
CreaturePtr & operator[](unsigned int index);
// Overload operator+. Operator+ concatenates two Packs
together,
// appending the element from the second Pack (rhs) to a new Pack
that
// contains all the elements from the 1st Pack (the invoking
object)
// in order. The input Packs are not modified. The resulting new
Pack
// is returned.
Pack operator+(const Pack & rhs) const;
};
#endif
Packcpp Animal.hpp Hunter.hpp + x main.cpp Creature.hpp (Global Scope) Wolf.hpp Ô Packhpp + Miscellaneous Files O#ifndef HUNTER_HPP 2 #define HUNTER_HPP 3 #include "Creature. hpp" 6 7 8 g 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // TODO: Create the Hunter class here. The Hunter class must public extend class Creature. If Hunter should extend Creature virtually as a fix to the diamond inheritance problem, then do so. Otherwise do not do this. // The Creature class must have the following members: // - A private data field of type double called attack. // - A public constructor that takes as input parameters two doubles. // This constructor must call Creature's constructor, passing the // 1st parameter to it. Then it must set attack to the 2nd parameter. // Give both of these parameter the default value of 1.0. // Make this constructor so that it prevents automatic type conversion (Hint: what keyword do you need to put in front of the constructor to // accomplish this?). Write this constructor inline. In Hunter override function strength(). Thus function must compute // and return getSize() + attack. Write this inline. // Do not add any more public members to Hunter than what is described above. Fendi
main.cpp Wolf.hpp Pack.hpp 3 Pack.cpp Animal.hpp Creature.hpp 8 + x Hunter.hpp ** Miscellaneous Files (Global Scope) #ifndef CREATURE_HPP 2 #define CREATURE_HPP 3 4 // TODO: Create the Creature class here. 5 The Creature class must have the following members: 6 - A private data field of type double called size. 7 - A public constructor that takes as input a double and 8 // initializes size to this parameter. Give this parameter to a default value of 1.0. Make this constructor so that 10 // it prevents automatic type conversion (Hint: what keyword // do you need to put in front of the constructor to accomplish 12 // this?). Write this constructor inline. // - A public virtual destructor that has an empty body. Write this inline. // A public get function for size called getSize(). Write this inline. // The public pure virtual function // virtual double strength( const Do not add any more public members to Creature than what is described above. ggs品与品呈员后台 #endif
Hunter.hpp main.cpp @ Wolf.hpp Packhpp Pack.cpp Animal.hpp @ + x Creature.hpp @ ++ Miscellaneous Files (Global Scope) #ifndef ANIMAL_HPP 2 #define ANIMAL_HPP 3 4 #include "Creature. hpp" 5 6 // TODO: Create the Animal class here. 7 The Animal class must public extend class Creature. 8 If Animal should extend Creature virtually as a fix to the 9 // diamond inheritance problem, then do so. Otherwise do not do this. 10 The Animal class must include the following line in it to 11 // inherit the constructor(s) from class Animal: 12 // using Creature:: Creature; 13 In Animal override function strength() to call getSize() and 14 // return this result. Write this inline. 15 // Do not add any more public members to Animal than what is described above. 16 17 18 #endif 19
Pack.cpp 8 + X Animal.hpp Hunter.hpp @ main.cpp 0 Wolf.hpp Pack.hpp ++ Miscellaneous Files #include <stdexcept> #include "Pack.hpp" Creature.hpp 0 (Global Scope) // TODO: 1 Implement constructor Pack:: Pack(unsigned int theSize). This constructor must set mySize to theSize. // Then it must dynamically allocate data field members 1/ to an array of mySize elements. 11 Finally, set each element in array members to nullptr. // TODO: Implement the copy constructor. This constructor must copy the pointer values in other members instead of making a deep copy of the objects these pointers point to. ♡// TODO: Implement the move constructor. // TODO: Implement the destructor to delete the array members. // Do not delete the objects that the pointers in [// array members refer to. Just delete the entire array. 27 28 // TODO: Implement the copy assignment operator. This operator must copy the pointer values in rhs.members instead of making a deep copy of the objects these pointers point to. דר Q// TODO: [11 Implement the move assignment operator. 35 36 37 38 38 39 39 JO 40 JU 4 42 13 // TODO: Overload operator const CreaturePtr & Pack::operator[](unsigned int index) const If index is outside the bounds of array members, then throw an instance of std::out_of_range{"Add message here"}. 11 This operator must return the element in members at position index. 115 * 16 40 47 40 49 50 2// TODO: Overload operator CreaturePtr & Pack::operator[](unsigned int index) If index is outside the bounds of array members, then throw an instance of std::out_of_range{ "Add message here"}. [// This operator must return the element in members at position index. 53 54 55 re 57 58 59 60 // TODO: Overload operator+. Operator+ concatenates two Packs together, 11 appending the element from the second Pack (rhs) to a new Pack that // contains all the elements from the 1st Pack (the invoking object) in order. The input Packs are not modified. The resulting new Pack [1] is returned.
Packcpp Animal.hpp 8 Hunter.hpp main.cpp Wolf.hpp + x Pack.hpp Miscellaneous Files #ifndef WOLF HPP #define WOLF_HPP Creature.hpp (Global Scope) #include "Animal.hpp" #include "Hunter.hpp" n 10 11 // TODO: Create the Wolf class here. 1 The Wolf class must public extend Animal and public extend Hunter. 1 If Hunter should extend any of these classes virtually as a fix to the diamond inheritance problem, then do so. Otherwise do not do this. Constructor: The Wolf class must have a public constructor that takes as input parameters two doubles. Give both of these parameter the default value of 1.0. This constructor must call Creature's constructor, passing it the 1st parameter. Then it must call Animal's constructor, passing it the 1st parameter. Finally, it must call Hunter's constructor, passing it the 1st and 2nd parameter in that order. 1 Make this constructor so that it prevents automatic type conversion (Hint: what keyword do you need to put in front of the constructor to accomplish this?). Write this constructor inline. In Wolf override function strength(). Thus function must call Animal's strength(), Hunter's strength(), take the average of these two values, and return this result. Write this inline. Do not add any more public members to Hunter than what is described above. 16 17 18 10 21 24 25 26 27 28 #endif
•class Creature will be the parent class for the other classes.
An Animal and a Hunter are both Creatures, so both
of these classes will extend Creature. A Wolf is both an Animal and
a Hunter, so it will extend both Animal and
Hunter (multiple inheritance).
•Class Pack will represent a collection of Creatures. It has an
internal pointer called members that refers to an array
of pointers to Creature objects. Near the top of file Pack.hpp we
use type aliasing to give the type Creature* the
additional name of CreaturePtr (this is done for convenience). This
allows us to write CreaturePtr in place of
Creature
•Take a look at the source code. Your task is to follow the
instructions given in the comments that start with TODO.
Make sure to add more testing code to main.cpp.
Main.cpp
#include
#include
#include "Wolf.hpp"
#include "Pack.hpp"
using namespace std;
// print strengths of all members in a Pack
void printStrengths(const Pack & p);
// deletes all members of a Pack
void deleteMembers(Pack & p);
int main()
{
Creature * c = new Wolf(25, 12);
cout << "c->size(): " << c->getSize() <<
endl; // 25
cout << "c->strength(): " << c->strength()
<< endl; // 31
Pack p1{3};
p1[0] = new Wolf(26, 13);
p1[1] = new Hunter(20.7, 14.6);
p1[2] = new Animal(29);
cout << "p1 strengths: ";
printStrengths(p1); // 32.5 35.3 29
try
{
p1[3] = nullptr;
cout << "(1) Error: Pack::operator[] did not throw an
out_of_range "
"exception as expected." << endl;
}
catch (const out_of_range & e)
{
cout << "(1) Pack::operator[] correctly throw an out_of_range
exception"
<< endl;
}
try
{
cout << p1[3]->strength() << endl;
cout << "(2) Error: Pack::operator[] did not throw an
out_of_range "
"exception as expected." << endl;
}
catch (const out_of_range & e)
{
cout << "(2) Pack::operator[] correctly throw an out_of_range
exception"
<< endl;
}
Pack p2{8};
p2[0] = new Wolf(24, 16);
p2[1] = new Wolf(23, 17);
p2[2] = new Animal(30.2);
p2[3] = new Hunter(21, 19);
p2[4] = new Wolf(20.4, 19.7);
p2[5] = new Wolf();
p2[6] = new Hunter();
p2[7] = new Animal();
cout << "p2 strengths: ";
printStrengths(p2); // 32 31.5 30.2 40 30.25 1.5 2 1
cout << "p3 = p1 + p2" << endl;
Pack p3 = p1 + p2;
cout << "p3 strengths: ";
printStrengths(p3); // 32.5 35.3 29 32 31.5 30.2 40 30.25 1.5 2
1
// TODO: add more testing code here.
// Make sure your code does not have a memory leak
// (every call to new must have a corresponding call to
delete).
// delete dynamically allocated data
deleteMembers(p1);
deleteMembers(p2);
delete c;
}
void printStrengths(const Pack & p)
{
for (unsigned int i=0; i < p.size(); i++)
{
if (i != 0) cout << " ";
cout << p->strength();
}
cout << endl;
}
void deleteMembers(Pack & p)
{
for (unsigned int i=0; i < p.size(); i++)
{
delete p;
p = nullptr;
}
}
Pack.hpp
#ifndef PACK_HPP
#define PACK_HPP
#include "Creature.hpp"
// Type alias for a pointer to a Creature.
// CreaturePtr is the same as writing Creature*
using CreaturePtr = Creature*;
class Pack
{
private:
unsigned int mySize; // number of elements in array members
CreaturePtr * members; // array of pointers to Creatures
public:
explicit Pack(unsigned int theSize);
Pack(const Pack & other); // copy constructor
Pack(Pack && other); // move constructor
~Pack(); // destructor
unsigned int size() const {return mySize;}
Pack & operator=(const Pack & rhs); // copy
assignment
Pack & operator=(Pack && rhs); // move assignment
// overload both versions of operator[]
const CreaturePtr & operator[](unsigned int index) const;
CreaturePtr & operator[](unsigned int index);
// Overload operator+. Operator+ concatenates two Packs
together,
// appending the element from the second Pack (rhs) to a new Pack
that
// contains all the elements from the 1st Pack (the invoking
object)
// in order. The input Packs are not modified. The resulting new
Pack
// is returned.
Pack operator+(const Pack & rhs) const;
};
#endif
Packcpp Animal.hpp Hunter.hpp + x main.cpp Creature.hpp (Global Scope) Wolf.hpp Ô Packhpp + Miscellaneous Files O#ifndef HUNTER_HPP 2 #define HUNTER_HPP 3 #include "Creature. hpp" 6 7 8 g 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // TODO: Create the Hunter class here. The Hunter class must public extend class Creature. If Hunter should extend Creature virtually as a fix to the diamond inheritance problem, then do so. Otherwise do not do this. // The Creature class must have the following members: // - A private data field of type double called attack. // - A public constructor that takes as input parameters two doubles. // This constructor must call Creature's constructor, passing the // 1st parameter to it. Then it must set attack to the 2nd parameter. // Give both of these parameter the default value of 1.0. // Make this constructor so that it prevents automatic type conversion (Hint: what keyword do you need to put in front of the constructor to // accomplish this?). Write this constructor inline. In Hunter override function strength(). Thus function must compute // and return getSize() + attack. Write this inline. // Do not add any more public members to Hunter than what is described above. Fendi
main.cpp Wolf.hpp Pack.hpp 3 Pack.cpp Animal.hpp Creature.hpp 8 + x Hunter.hpp ** Miscellaneous Files (Global Scope) #ifndef CREATURE_HPP 2 #define CREATURE_HPP 3 4 // TODO: Create the Creature class here. 5 The Creature class must have the following members: 6 - A private data field of type double called size. 7 - A public constructor that takes as input a double and 8 // initializes size to this parameter. Give this parameter to a default value of 1.0. Make this constructor so that 10 // it prevents automatic type conversion (Hint: what keyword // do you need to put in front of the constructor to accomplish 12 // this?). Write this constructor inline. // - A public virtual destructor that has an empty body. Write this inline. // A public get function for size called getSize(). Write this inline. // The public pure virtual function // virtual double strength( const Do not add any more public members to Creature than what is described above. ggs品与品呈员后台 #endif
Hunter.hpp main.cpp @ Wolf.hpp Packhpp Pack.cpp Animal.hpp @ + x Creature.hpp @ ++ Miscellaneous Files (Global Scope) #ifndef ANIMAL_HPP 2 #define ANIMAL_HPP 3 4 #include "Creature. hpp" 5 6 // TODO: Create the Animal class here. 7 The Animal class must public extend class Creature. 8 If Animal should extend Creature virtually as a fix to the 9 // diamond inheritance problem, then do so. Otherwise do not do this. 10 The Animal class must include the following line in it to 11 // inherit the constructor(s) from class Animal: 12 // using Creature:: Creature; 13 In Animal override function strength() to call getSize() and 14 // return this result. Write this inline. 15 // Do not add any more public members to Animal than what is described above. 16 17 18 #endif 19
Pack.cpp 8 + X Animal.hpp Hunter.hpp @ main.cpp 0 Wolf.hpp Pack.hpp ++ Miscellaneous Files #include <stdexcept> #include "Pack.hpp" Creature.hpp 0 (Global Scope) // TODO: 1 Implement constructor Pack:: Pack(unsigned int theSize). This constructor must set mySize to theSize. // Then it must dynamically allocate data field members 1/ to an array of mySize elements. 11 Finally, set each element in array members to nullptr. // TODO: Implement the copy constructor. This constructor must copy the pointer values in other members instead of making a deep copy of the objects these pointers point to. ♡// TODO: Implement the move constructor. // TODO: Implement the destructor to delete the array members. // Do not delete the objects that the pointers in [// array members refer to. Just delete the entire array. 27 28 // TODO: Implement the copy assignment operator. This operator must copy the pointer values in rhs.members instead of making a deep copy of the objects these pointers point to. דר Q// TODO: [11 Implement the move assignment operator. 35 36 37 38 38 39 39 JO 40 JU 4 42 13 // TODO: Overload operator const CreaturePtr & Pack::operator[](unsigned int index) const If index is outside the bounds of array members, then throw an instance of std::out_of_range{"Add message here"}. 11 This operator must return the element in members at position index. 115 * 16 40 47 40 49 50 2// TODO: Overload operator CreaturePtr & Pack::operator[](unsigned int index) If index is outside the bounds of array members, then throw an instance of std::out_of_range{ "Add message here"}. [// This operator must return the element in members at position index. 53 54 55 re 57 58 59 60 // TODO: Overload operator+. Operator+ concatenates two Packs together, 11 appending the element from the second Pack (rhs) to a new Pack that // contains all the elements from the 1st Pack (the invoking object) in order. The input Packs are not modified. The resulting new Pack [1] is returned.
Packcpp Animal.hpp 8 Hunter.hpp main.cpp Wolf.hpp + x Pack.hpp Miscellaneous Files #ifndef WOLF HPP #define WOLF_HPP Creature.hpp (Global Scope) #include "Animal.hpp" #include "Hunter.hpp" n 10 11 // TODO: Create the Wolf class here. 1 The Wolf class must public extend Animal and public extend Hunter. 1 If Hunter should extend any of these classes virtually as a fix to the diamond inheritance problem, then do so. Otherwise do not do this. Constructor: The Wolf class must have a public constructor that takes as input parameters two doubles. Give both of these parameter the default value of 1.0. This constructor must call Creature's constructor, passing it the 1st parameter. Then it must call Animal's constructor, passing it the 1st parameter. Finally, it must call Hunter's constructor, passing it the 1st and 2nd parameter in that order. 1 Make this constructor so that it prevents automatic type conversion (Hint: what keyword do you need to put in front of the constructor to accomplish this?). Write this constructor inline. In Wolf override function strength(). Thus function must call Animal's strength(), Hunter's strength(), take the average of these two values, and return this result. Write this inline. Do not add any more public members to Hunter than what is described above. 16 17 18 10 21 24 25 26 27 28 #endif