我在基类和派生类中都有一个方法。当我在派生类中的对象上调用此方法时,它调用基类方法而不是派生类方法。这是我的代码:
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;
}
在addPerson<Student>(personVector);
创建的对象
创建对象时,它将创建为学生,因为它会调用学生构造器。
调用的方法:personVector[num-1].coutPerson();
Student对象是被告知coutPerson的对象,因为它显示了我在创建Student对象时给出的信息。
template<typename T> void addPerson(vector<Person> &personVector) {
T p;
personVector.push_back(p);
}
当在Student对象上调用coutPerson()方法时,它只会播放名称,birthday,phoneNumber和city&amp;州。这段代码有什么问题?它应该调用Student coutMethod ...
谢谢!
答案 0 :(得分:7)
您可能会在某个时刻将Student
对象复制到Person
对象,从而导致Object Slicing Problem。例如,您可能将它们存储在vector<Person>
中。您需要使用指针或引用,而不是复制对象。
要解释为什么这是一个问题,您必须意识到向量不存储您在push_back
中传递给它的实际对象,它存储对象的副本。将Student
复制到Person
时,副本不再是Student
。
答案 1 :(得分:3)
您的personVector
包含Person
个对象。不是对Person
个对象的引用,而是对实际的Person
个对象的引用。当你“将Student
对象放入向量”时,真正发生的是向量构造一个 new Person
对象,该对象使用{{1进行复制初始化您赋予它的对象,也就是说,它会创建Student
对象的Person
部分的副本。此行为也称为“切片”。
由于向量中没有Student
个对象,但只有Student
个对象,因此调用Person
上的coutPerson
调用Person::coutPerson
而不是{{}就不足为奇了1}}。
如果您需要多态行为,则必须在容器中存储指针(最好是智能指针,如Student::coutPerson
或shared_ptr
)。但请注意,您在函数中构造的对象unique_ptr
在返回时被销毁,因此为了使对象生存(因此您可以指向它),您必须使用p
分配它。
答案 2 :(得分:1)
功能很好。您要么从coutPerson
类型的对象调用Person
,要么从Person
的构造函数/析构函数中调用它(感谢@celtschk)。
您应该通过指针或引用调用Person
类型的对象。这就是你如何获得多态性。