如何正确使用虚函数

时间:2019-03-06 10:48:15

标签: c++

我正在课程中学习c ++-我们只是在学习虚函数

我们有一个任务来创建一个基类:Car

和3个派生类:

  • 市民
  • 奥德赛
  • 法拉利

基类具有一个name成员变量(带有getter和setter)和一个getDoorSpecs函数,该函数返回默认值

每个子类也都有getDoorSpecs,我们应该将其创建为虚拟函数。

我们为我们提供了一个主函数,不允许我们对其进行修改,并且我们必须创建一个单个函数attachDoors()来接收每个子类的实例-并使用正确的getDoorSpecs返回一个值。

我以为我终于正确创建了虚函数-但是当我运行它时,我显然还不明白如何创建attachDoors函数来利用子类的虚函数。我以为,如果我先调用基类,然后再调用该函数,则子类方法将覆盖它,但是虽然可以正常编译,但它给我的输出并不正确。

这是我的代码:

#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;
}

这是给出的输出:

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

这是我试图获得的输出:

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 

根据我们被要求执行此操作的方式,我知道,只需对该功能进行较小的更改就可以实现正确的输出:

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

但是,如果我能弄清楚该怎么做,我会感到很震惊。 (我在此处已阅读了许多答案-但没有一个点击可以给我我想要的洞见)

老实说,我确实在为这门课程而苦苦挣扎,但是当我能够使事情正常进行时,并且在很多时候我能弄清楚这一点时,我感到很高兴,而这次显然不是。任何帮助表示感谢!

1 个答案:

答案 0 :(得分:7)

您将需要使用指针或对基类的引用来引用派生类对象。调用该对象的虚函数并执行该函数的派生类版本:

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

另请参阅:Why do virtual functions need to be passed with a pointer and not by value(of the object)?