This question already has answers here:
What is object slicing?

(18个回答)


7年前关闭。




我有以下设置:

main.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();
    }
}

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

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

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

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

GuidedTour继承自Tour类,并且我已经在基本Tour类中将display()函数指定为虚拟的,但是由于某些原因,从来没有调用GuidedTour display()函数,每次都仅调用基本函数。我究竟做错了什么?

最佳答案

您的代码实际上不输出任何内容,因为std::vector最初为空。除此之外,您的问题是由对象切片引起的(我假设您是push_back()并将GuidedTour放入 vector 中)。

进行对象切片时,您仅存储Tour对象的GuidedTour部分,这就是为什么看到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 ed指针。使用它们将极大地减轻您手动管理对象并对其进行delete编码的问题,有时[低估]是导致错误和未定义行为的原因。

请注意,有些人可能建议您使用boost::ptr_vector或类似的名称。听他们的话,尤其是当他们给您争论为什么他们比其他选择更好时。

关于C++覆盖的虚函数未得到调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18841606/

10-10 23:29