我有一个用C ++编写的功课来编写一所大学。 我有两个主要的抽象类学生和课程。 在课程中,有不同的子类,如SoftwareEngineering类等 在学生中,有不同的子课程,例如SoftwareEngineering学生班等。
现在,在课程子课程中,每个子课程都有注册学生的功能
void register(Student &s);
当我调用每个课程子课程的功能寄存器(例如软件工程课程)时,我想将该学生参考推送到矢量中。 但我收到了错误
cannot allocate an object of abstract type 'Student'
Student类是抽象的,并且有子类SoftwareEngineeringStudent等。 但我 - 必须让寄存器功能得到一个抽象对象学生,而不是像SoftwareEngineeringStudent那样的特定类型的学生。
有可能解决这个问题吗?
这里是一个骨架(当然不是完整的代码!):
//Course.h
class Course{
virtual void reg(Student &s)=0
}
class SoftwareEngCourse : public Course{
void reg(Student &s);
}
//Student.h
class Student{
virtual void study(Course &c)=0;
}
class SoftwareEngStudent : public Student{
void study(Course &c);
}
现在在Course.cpp中:
//Course.cpp
void SoftwareEngCourse::reg(Student &s){
vector_of_Student_object.push_back(s);
}
答案 0 :(得分:5)
在评论中你说你的向量被声明为:
std::vector<Student> vector_of_Student_object;
......其中存在问题。您尝试在Student
中存储vector
个对象,但无法存储Student
对象,因为该类是抽象的。请考虑以下psudocode:
void foo(Student s)
{
}
int main()
{
SoftwareStudent ss;
foo(ss);
}
调用ss
时foo
会发生什么?您传递的是SoftwareStudent
,但foo
只需Student
。因此,ss
被隐式转换为其基类Student
,由于foo
按Student
取值,因此尝试通过调用以下内容来构造新的Student
:
Student::Student(const Student& rhs)
换句话说,SoftwareStudent
的{{1}}特定属性
您可能没有自己实现此构造函数,在这种情况下编译器会为您执行此操作。
最终结果是您尝试实例化抽象类,因为ss
采用foo
个值。这显然不起作用,因为你无法实例化一个抽象类。
这与您的实际问题有关,因为Student
是vector
个vector
个对象,按值再次存储。将对象插入向量时,将复制该对象。您最终尝试实例化Student
对象,这是您无法做到的,因为Student
是抽象的。
您需要存储Student
以外的其他内容,Student
引用或指针。由于您不能拥有Student
个引用,因此会留下指针。
每当处理指针时,最好处理智能指针而不是原始指针,就像使用智能指针一样,你不必担心释放对象,而且通常你甚至不必使用{{ 1}}显式。 vector
可能是最容易合并的,尽管new
在语义上可能更合适。
答案 1 :(得分:3)
是的,让vector_of_Student_object
成为学生(智能)指针的向量。
对象的向量可能不是你想要的,因为对象将是sliced。