Virtual Method not calling dervied class method. - C++

久未见 提交于 2019-12-11 07:32:01

问题


I have a method in both the base class and the derived class. When I call this method on an object in the derived class it calls the base class method and not the derived class method. Here is my code:

Person.h

class Person
{
...
public:
...
    virtual void coutPerson();
};

Person.cpp

void Person::coutPerson() {
    cout << name << endl;
    birthday.coutDate();
    phoneNumber.coutPhoneNumber();
    cout << city << ", " << state << endl;
}

Student.h

class Student : public Person
{
...
public:
...
    virtual void coutPerson();
};

Student.cpp

void Student::coutPerson() {
    cout << "DEBUG: Student::coutPerson()" << endl;
    //Person::coutPerson();
    cout << "Dorm Room: " << this->dorm << " " << this->dormRoom << endl;
}

Object created at: addPerson<Student>(personVector); When object is created it is created as a Student because it calls the Student construtor. Method called at: personVector[num-1].coutPerson(); The Student object is the one being told to coutPerson because it is displaying the info that I gave it when I created the Student object.

template<typename T> void addPerson(vector<Person> &personVector) {
    T p;
    personVector.push_back(p);
}

When the coutPerson() method is called on a Student object it only couts the name, birthday, phoneNumber, and city & state. What is wrong with this code? It should be calling the Student coutMethod...

Thanks!


回答1:


Your personVector contains Person objects. Not references to Person objects, but actual Person objects. When you "put your Student object into the vector", what really happens is that the vector constructs a new Person object, which is copy-initialized with the Student object you give to it, that is, it creates a copy of the Person part of the Student object. This behaviour is also known as "slicing".

Since there is no Student object in the vector, but only a Person object, it is no surprise that calling coutPerson on it calls Person::coutPerson, not Student::coutPerson.

If you want polymorphic behaviour, you have to store pointers (preferably smart pointers like shared_ptr or unique_ptr) in the container. Note however that the object p you constructed in your function is destroyed on return, so for the object to survive (so you can have a pointer to it) you have to allocate it with new.




回答2:


You are probably copying the Student object to a Person object at some point, leading to the Object Slicing Problem. For example you may be storing them in a vector<Person>. You need to use a pointer or reference instead of copying the object.

To explain why this is a problem, you must realize that a vector doesn't store the actual object you pass to it in push_back, it stores a copy of the object. When you copy a Student to a Person, the copy isn't a Student anymore.




回答3:


The functions are fine. You're either calling coutPerson from an object of type Person, or calling it from inside Person's constructor/destructor (thanks @celtschk).
You should be calling via a pointer or reference to an object of type Person. That's how you obtain polymorphism.



来源:https://stackoverflow.com/questions/8348939/virtual-method-not-calling-dervied-class-method-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!