2

Student という親クラスがあります。子クラス StudentCS があります。

Student.h:

#include <iostream.h>
#include<string.h>
#include<vector.h>
#include "Course.h"
class Course;

class Student {
public:
    Student();
    Student(int id, std::string dep, std::string image,int elective);
    virtual ~Student();
    virtual void Study(Course &c) const;  // this is the function we have a problem with
    void setFailed(bool f);
[...]

};

Student.cpp:

#include "Student.h"

[...]

void  Student::Study(Course &c) const {

}

そして、StudentCS.h があります。

#include "Student.h"
class StudentCS : public Student {
public:
StudentCS();
virtual ~StudentCS();
StudentCS (int id, std::string dep, std::string image,int elective);
void Study(Course &c) const;
void Print();
};

そして StudentCS.cpp:

void StudentCS:: Study (Course &c) const{
    //25% to not handle the pressure!
    int r = rand()%  100 + 1;
cout << r << endl;
if (r<25) {
    cout << student_id << " quits course " << c.getName() << endl;
}

 }

主に学生を作成します。

Student *s;
vector <Student> uniStudent;
[...]
    if(dep == "CS")
        s = new  StudentCS(student_id,dep,img,elective_cs);
    else
        s = new StudentPG(student_id,dep,img,elective_pg);

    uniStudent.push_back(*s);

それから私たちは勉強するよう呼びかけますが、子供ではなく親が勉強します!助けてください!

コードはコンパイルされますが、実行されて uniStudent.Study() で呼び出されると、子ではなく親が使用されます

4

1 に答える 1

7

編集:編集後、問題は明確です。

問題は、ベース コンクリート オブジェクトを STL コンテナーに格納していることです。これにより、オブジェクトのスライスと呼ばれる問題が発生します。

学生を に追加するvector<Student>と、ベクトルのアロケータはクラスに基づいて構築されるため、Student派生クラスに関するすべての追加情報は単に破棄されます。ベクターに要素を挿入すると、基本型になります。

問題を解決するには、 を使用してvector<Student*>、学生への直接参照を保存する必要があります。したがって、アロケーターはポインターに関連しているだけで、オブジェクトをスライスしません。

vector<Student*> uniStudent;
...
uniStudent.push_back(s);
uniStudent[0]->study();

より堅牢な方法ですべてを管理するには、スマート ポインターを使用することをお勧めします。

于 2012-11-21T18:43:13.287 に答える