Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

i need help with this c++ assignment. It's about constructors and how to define a couple of classes and to use them polymorphically. This is

i need help with this c++ assignment. It's about constructors

and how to define a couple of classes and to use them polymorphically.

This is the starting code for this question.

#include

#include

#include

#include

#include

#include

class animal

{

public:

virtual ~animal() { }

virtual std::string kind() const = 0;

};

using animal_ptr = std::unique_ptr;

template

animal_ptr make_animal(T&& t)

{

using type = std::remove_cvref_t;

return animal_ptr{ new type(std::forward(t)) };

}

Writing the Cat Class

Define a class called cat as follows:

  • the class needs to inherit publicly and virtually from animal,
  • the class has a single public member kind() that overrides the kind() (abstract) function in animal and returns "Felis catus"s.

Tips:

  • The s following "Felis catus" involves the C++ literal operator. The s makes the quoted string literal a std::string object instead of a const char [12] object. To use s like this, ensure you have using namespace std::literals; inside this function (or some suitable place elsewhere).
  • When writing kind() don't write virtual in front of it BUT do add override after the const. A function that has the same signature name as a virtual function in the parent class is automatically virtual, thus, you don't need to add virtual again. By adding override (which is optional) you are telling the compiler you intend to override a virtual function. If for some reason your function doesn't actually override a virtual function, the compiler will report an error. (NOTE: If you don't use override, the compiler has no way of knowing what you intended and cannot report an error. This is why override was added to C++.)

The cat class is intended to be very simple: it simply outputs its genus and species with kind().

Writing the Dog Class

Define a class called dog as follows:

  • the class needs to inherit publicly and virtually from animal,
  • the class has a single private data member of type std::string (choose a variable name to use),
  • the class has a deleted default constructor,
  • the class has a defaulted copy constructor,
  • the class has a defaulted copy assignment operator,
  • the class has a constructor accepting a std::string const& parameter which is the name of the dog being constructed, (This constructor must also set the value of the private data member std::string using direct initialization BEFORE the opening '{' of the constructor.)
  • the class has a kind() member function that overrides animal::kind and returns "Canis lupus familiaris"s, and,
  • the class has a name() member function that returns the type std::string const&, i.e., it returns the private data member defined earlier. (This function must also be const-qualified).

Tips:

  • Visit the linked-to cppreference.com pages for more information. Look up the corresponding item in the ATOCPP textbook.
  • By design there is no way to change the value of a dog's name once it has been set via the constructor.

Writing the dogcat Class

Unfortunately you have to deal with hybrid organisms too --so you need to define a class called dogcat as follows:

  • the class (multiply) inherits both publicly and virtually from both dog and from cat,
  • the class has a default constructor that invokes the parent dog constructor with the name "hybrid" and the default cat constructor,
  • the class has a constructor that has two parameters (dog const& d and cat const& c) and invokes the corresponding parameter class' copy constructor passing in d or c respectively,
  • the class has a defaulted copy constructor,
  • the class has a defaulted copy assignment operator, and,
  • the class has a kind() member function that overrides animal::kind and returns the result of calling dog's kind(), + (i.e., string append), the string " + ", + (i.e., string append), and calling cat's kind().

Tips:

  • A dogcat's kind() function returns a string that is a concatenation of its dog's kind(), " + ", and its cat's kind().
  • A dogcat's name is always "hybrid" if default constructed.

Writing operator+(dog const& d, cat const& c)

To make it easier to create dogcat hyrbids, write an operator +() overload as follows:

  • the function has two parameters: dog const& d and cat const& c,
  • the function return type is dogcat, and,
  • the return expression must create a dogcat object from d and c passing in d and c to a dogcat constructor.

Writing main()

The above classes will now be used in main() as follows:

  • declare a std::vector variable called v,
  • declare a variable, d, of type dog passing in the name "Fido",
  • default construct a variable of type cat called c,
  • call v.push_back() with the result of calling make_animal(d),
  • call v.emplace_back() with the result of dynamically allocating a cat value using operator new,
  • call v.push_back() with the result of calling make_animal(d+c).

The variable v is effectively an array of pointers to animal objects. Its pointers are, however, stored in a "smart pointer" type called std::unique_ptr which will automatically call operator delete when it is destroyed. Another useful smart pointer type is called std::shared_ptr which allows multiple std::shared_ptr variables to refer to the same object. Like std::unique_ptr, std::shared_ptr also ensures that the dynamically allocated memory associated with its contents is also destroyed. This is why this program does not directly call operator delete to free allocated memory. So the fact that C++ does not have garbage collection is not really an issue: one can make use of C++ destructors in types to "clean up" resources. When this is done, this coding pattern is called RAII (Resource Acquisition Is Initialization).

With the above, let's process polymorphically the animals in the vector object as follows:

  • open a (multi-line) range-for loop over all elements e of v (each element type should be auto const&, or if you prefer, animal_ptr const&) and inside the for loop:
  • output to std::cout the output of e's kind() member function,
  • create a variable called p of type dog* and assign the result of dynamically casting the result of calling e.get() to dog*,
  • if p is not nullptr then output to std::cout the string ", name = " (without quotes), followed by the result of calling the name() function pointed to by p, and,
  • output the newline character to std::cout.

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

How To Make A Database In Historical Studies

Authors: Tiago Luis Gil

1st Edition

3030782409, 978-3030782405

More Books

Students also viewed these Databases questions