问题
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