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) 最初の選択肢 (オブジェクトの削除) で、削除するオブジェクトの静的型が動的型と異なる場合、静的型は、削除するオブジェクトの動的型と静的型の基本クラスでなければなりません。仮想デストラクタがなければ、動作は未定義です。2 番目の選択肢 (配列の削除) では、削除するオブジェクトの動的な型がその静的な型と異なる場合、動作は未定義です。

そのような理由はおそらく、派生クラスのデストラクタの呼び出し (仮想関数の呼び出しなど) を、それを必要としないクラスにオーバーヘッドを追加することなく処理できるためです (つまりvirtual、デフォルトでデストラクタを導入してすべてのクラスをポリモーフィックにしないでください)。この特定のケースを処理するためだけに)。

于 2013-02-06T14:25:54.370 に答える