虚方法不调用dervied类方法. - C++

mic*_*ahl 1 c++ virtual inheritance

我在基类和派生类中都有一个方法.当我在派生类中的对象上调用此方法时,它调用基类方法而不是派生类方法.这是我的代码:

Person.h

class Person
{
...
public:
...
    virtual void coutPerson();
};
Run Code Online (Sandbox Code Playgroud)

Person.cpp

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

Student.h

class Student : public Person
{
...
public:
...
    virtual void coutPerson();
};
Run Code Online (Sandbox Code Playgroud)

Student.cpp

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

创建的addPerson<Student>(personVector); 对象:创建对象时,它创建为Student,因为它调用Student construtor.调用的方法:personVector[num-1].coutPerson(); Student对象是告诉coutPerson的对象,因为它显示了我在创建Student对象时给出的信息.

template<typename T> void addPerson(vector<Person> &personVector) {
    T p;
    personVector.push_back(p);
}
Run Code Online (Sandbox Code Playgroud)

当在Student对象上调用coutPerson()方法时,它只会传播名称,生日,电话号码以及城市和州.这段代码有什么问题?它应该是调用学生coutMethod ...

谢谢!

Mar*_*som 7

您可能在某个时刻将Student对象复制到对象Person,导致对象切片问题.例如,您可能将它们存储在一个vector<Person>.您需要使用指针或引用而不是复制对象.

要解释为什么这是一个问题,你必须意识到一个向量不存储你传递给它的实际对象push_back,它存储了一个对象的副本.将a复制Student到a时Person,副本Student不再存在.


cel*_*chk 6

您的personVector包含Person对象。不是对Person对象的引用,而是对实际Person对象的引用。当你“把你的Student对象为载体”,真正发生的是,载体构建一个新的 Person对象,这是复制初始化与Student你给它的对象,也就是说,它会创建一个副本中的Person中的一部分Student对象。这种行为也称为“切片”。

由于Student向量中没有对象,只有一个Person对象,因此调用coutPerson它也就不足为奇了Person::coutPerson,而不是Student::coutPerson

如果您想要多态行为,您必须在容器中存储指针(最好是像shared_ptr或 之类的智能指针unique_ptr)。但是请注意,p您在函数中构造的对象在返回时会被销毁,因此为了使对象存活(以便您可以拥有指向它的指针),您必须使用new.