C++未调用覆盖的虚拟函数

C++ overridden virtual function not getting called

本文关键字:虚拟 函数 覆盖 调用 C++      更新时间:2023-10-16

我有以下设置:

主.cpp:

int main()
{
    vector <Tour> tourList;
    Tour* tour_ptr;
    for (unsigned int i = 0; i < tourList.size(); i++)
    {
        tour_ptr = &tourList[i];
        tour_ptr->display();
    }
}

旅游:

class Tour
{
   public:
    virtual void display();
};

行程.cpp:

void Tour::display()
{
    cout << "Tour ID: " << getID() << "n";
    cout << "Description: " << getdescription() << "n";
    cout << "Tour Fee: $" << getfee() << "n";
    cout << "Total Bookings: " << getbookings() << "nn";
}

GuidedTour.h:

class GuidedTour : public Tour
{
    public:
            void display();
};

导览.cpp:

void GuidedTour::display()
{
    Tour::display();
    cout << "Max Tour Group Size: " << getMaxTourists() << "n";
    cout << "Tour Guide: " << getGuideName() << "n";
    cout << "Tour Date: " << getTourDate() << "nn";
}

GuidedTour 继承自 Tour 类,我在基 Tour 类中将 display() 函数指定为虚拟函数,但由于某种原因,GuidedTour display() 函数永远不会被调用,只有基函数每次都被调用。我做错了什么?

您的代码实际上不会打印任何内容,因为std::vector最初为空。除此之外,您的问题是由对象切片引起的(我假设您正在push_back() GuidedTour向量)。

当对象切片发生时,您只存储GuidedTour对象的Tour部分,这就是您看到Tour::display()输出的原因。

要解决您的问题,您需要通过使用(智能)指针和动态分配对象来多态地存储对象。

int main()
{
    vector <std::unique_ptr<Tour>> tourList;
    for(...) {
       tourList.push_back(std::make_unique<GuidedTour>(/* constructor parameters */));
       ...
       tourList.push_back(std::make_unique<Tour>(/* constructor parameters */));
    }
    for (unsigned int i = 0; i < tourList.size(); i++)
    {
        tourList[i]->display();
    }
}

请注意,我使用的是std::unique_ptr/std::make_unique而不是原始new指针。使用它们可以极大地缓解手动管理和delete对象的问题,有时[轻描淡写]是错误和未定义行为的原因。

请注意,有些人可能会建议您使用boost::ptr_vector或类似的东西。听听他们说,特别是如果他们给你论据,说明为什么他们比替代品更好。

你的问题与你的类无关,而是你如何创建对象。 tourList 向量中的每个元素都是一个 tour,在编译时或运行时没有任何内容可以确定它们是 GuidedTours。 实际上,GuidedTour 永远不会被调用,因为我在任何地方都没有在您的主对象中看到 GuidedTour 对象。

我同意"这是皮特"。 因为您还没有使用过 GuidedTour 类。如果您使用以下方法,它将起作用。

int main()
{
  vector <GuidedTour> tourList;
  Tour* tour_ptr;
  for (unsigned int i = 0; i < tourList.size(); i++)
  {
      tour_ptr = &tourList[i];
      tour_ptr->display();
  }
}