3

I am learning c++ in a course - and we are just learning virtual functions

We have an assignment to create a base class: Car

and 3 derived classes:

  • Civic
  • Odyssey
  • Ferrari

the base class has a name member variable (with a getter & setter) and a getDoorSpecs function returning a default value

each of the child classes also has the getDoorSpecs and we are supposed to create it as a virtual function.

We are supplied a main function as a driver that we are not allowed to modify, and we must create a single function attachDoors() that can receive an instantiation of each of the child classes - and use the correct getDoorSpecs to return a value.

I thought I finally got the virtual functions created right - but when I ran it I have clearly not understood how to create the attachDoors function to make use of the virtual functions of the child classes. I thought if I called the base class and then the function it would be overridden by the child class method - but while it compiles fine - it gives me not quite the right output.

Here is my code:

#include <iostream>
#include <string>
using namespace std;

class Car
{
public:
   string name;

   Car() {
      name = "Unknown model";}

   string getName(){
      return name;}

   void setName(string iName){
      name = iName;}

   virtual string getDoorSpecs(){
      return "Unknown doors";}
};

class Civic   :   public Car
{
public:
   Civic(){
      name = "Civic";}

   virtual string getDoorSpecs() override{
      return "4 doors";}
};

class Odyssey   :   public Car
{
public:
   Odyssey(){
      name = "Odyssey";}

   virtual string getDoorSpecs() override{
      return "2 front doors, 2 sliding doors, 1 tail gate";}
};

class Ferrari   :   public Car
{
public:
   Ferrari(){
      name = "Ferrari";}

   virtual string getDoorSpecs() override{
      return "2 butterfly doors";}
};

/**********************************************************************
 * Function: attachDoors
 * Purpose: This function can accept any type of Car object. It will
 *  call the appropriate functions to display the name and the doors info.
 ***********************************************************************/

// TODO: Include your attachDoors function here
void attachDoors(Car iVehicle)
{
   cout << "Attaching doors to "
        << iVehicle.getName()
        << " - "
        << iVehicle.getDoorSpecs()
        << endl;
}

/**********************************************************************
 * Function: main
 * Purpose: This is the entry point and driver for the program.
 ***********************************************************************/
int main()
{
   // You should not change main

   Civic civic;
   Odyssey odyssey;
   Ferrari ferrari;

   attachDoors(civic);
   attachDoors(odyssey);
   attachDoors(ferrari);

   return 0;
}

And here is the output this gives:

Attaching doors to Civic - Unknown doors 
Attaching doors to Odyssey - Unknown doors 
Attaching doors to Ferrari - Unknown doors

This is the output I was trying to get:

Attaching doors to Civic - 4 doors
Attaching doors to Odyssey - 2 front doors, 2 sliding doors, 1 tail gate
Attaching doors to Ferrari - 2 butterfly doors 

By how we have been asked to do this I KNOW it will be possible to achieve the right output with probably only a minor change to this function:

void attachDoors(Car iVehicle)
{
   cout << "Attaching doors to "
        << iVehicle.getName()
        << " - "
        << iVehicle.getDoorSpecs()
        << endl;
}

But I'm blowed if I can figure out what I should do. (I have read a number of answers here on SO - but none of them clicked to give me the insight I am trying for)

I honestly feel like I am really struggling with this course, but I am enjoying it when I can get things to work and a lot of the time I can figure it out, just not this time apparently. Any help gratefully appreciated!

kiltannen
  • 1,057
  • 2
  • 12
  • 27

1 Answers1

7

You would need to refer to a derived class object using a pointer or a reference to the base class. Call a virtual function for that object and execute the derived class's version of the function:

void attachDoors(Car& iVehicle)
{
   cout << "Attaching doors to "
        << iVehicle.getName()
        << " - "
        << iVehicle.getDoorSpecs()
        << endl;
}

Also see: Why do virtual functions need to be passed with a pointer and not by value(of the object)?

AMA
  • 4,114
  • 18
  • 32
  • YES! Thank you! I was SO CLOSE! I even thought it was a pointer thing - and tried with a * BUT of course no dice. It was simply needing to pass by reference &. Your answer is brilliant thank you! You are not just telling me how to do it - but helping me to understand the principle! Thanks again! – kiltannen Mar 06 '19 at 10:57
  • 1
    @kiltannen I'm glad it was helpful :) – AMA Mar 06 '19 at 10:59