0
class Person
{
public:
    Person(std::string& name,long id) : name_(name), id_(id) {}
    ~Person() {}
private:
    std::string& name_;
    long id_;
};

class Student : public Person
{
public:
    Student(std::string& name, long id) : Person(name,id) {}
    Student(std::string& name, long id, const std::vector<int*>& courses) : Person(name,id), courses_(courses) {}
    virtual ~Student() {
        std::vector<int*>::iterator it;
        for (it = courses_.begin(); it != courses_.end(); ++it)
        delete (*it);
    }
    const std::vector<int*>& getCourses() const { return courses_; }
private:
    std::vector<int*> courses_;
};

int main(){
    std::string name("Rina");
    std::vector<int*> courses;
    courses.push_back(new int(1345));
    Person* p = new Student(name,37,courses);
    Student* s = (Student*)p;
    std::cout << (*(s->getCourses().at(0)));
    delete p;
}

据我了解

delete p;

让我们意识到问题

~Person()

不是虚拟的。我的问题是:为什么要

~Person() 

是虚拟的?

4

2 回答 2

2

出于同样的原因,您将其他方法设为虚拟。

Person *p;
...

delete p;

Person如果析构函数不是虚拟的,将无法正确处理的子类。即它只会调用Person组件而不是子类组件(例如Employee

于 2013-02-06T14:23:39.290 回答
1

因为这就是标准所说的。delete p;否则是未定义的行为。

5.3.5 删除[expr.delete]

3)在第一种选择(删除对象)中,如果待删除对象的静态类型与其动态类型不同,则静态类型应为待删除对象的动态类型和静态类型的基类应具有虚拟析构函数或行为未定义。在第二种选择(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义。

之所以会这样,可能是因为它能够处理调用派生类析构函数(如调用虚函数),而不会给不需要它的类增加开销(即virtual默认情况下不要通过引入析构函数来使所有类多态)只是为了处理这种特殊情况)。

于 2013-02-06T14:25:54.370 回答