3

我想知道解决这个问题的更好方法:

一名教师可以教授多个学科,也可以在实验室学习更多内容,或者两者都在一个研究所。Lab, Subject,Teacher还有一些其他的变量。我没有把它们都写在这里。lab,subject and teacher可以单独添加新的。添加老师时,我只输入Teacher classandlabCode和的所有变量subCode。有一些实验室和主题是预定义的,还有一些是稍后添加的。我可以查看老师的记录,该记录还显示了他的实验室和主题详细信息(如果有)。

我在 c++ 中的概念不是太强,我不知道哪个更适合这个。我应该在教师课上给 Lab 和 Subject 课一个指针,还是我应该固有它们,或者有没有更好的方法来做到这一点。

class Lab{
    char labCode[20];
    char labName[40];
        int labYear;
    //here default constructor 
};
class Subject{

    char subCode[20];
    char subName[20];
        int subYear;
    //here default constructor 
};
//-------------------------------------
class Teacher{
    char facName[30];
    int teacherSubCount;
        int teacherLabCount;
    Subject *subject;
        Lab *lab;
    //here default constructor 

};
//------------or should i do like this--------------
class Teacher:public Lab,public Subject{
   char teacherName[30];
    int teacherSubCount;
        int teacherLabCount; 
   //here default constructor 

};

如果您可以建议任何教程,以便我可以学习指针的力量,因为我的书指出“指针非常强大的 C++”,但它们只给出了一些简单的例子:)

4

6 回答 6

4

“偏爱‘对象组合’而不是‘类继承’。” -四人帮

但是,更具体到您的课程,首先问自己......“教师是一种实验室还是一种学科?” 显然,答案是“不”。

在继承模型中,子类本身应该是父类的实例。考虑到Liskov Substitution Principle,该子对象应该被视为该父对象。因此,如果有正在寻找 a 的代码,Subject您可以将它传递给Teacher. 直观地说,这没有多大意义,也不是对正在建模的现实世界领域实体的准确表示。

在这种情况下,您肯定想要对象组合而不是类继承。有Teacher 一个 Lab有一个 Subject,不是是一个 Lab或是一个 Subject。实际上,如果Teacher可以多个Labs 或Subjects 那么组合将简单地从单个实例类成员更改为某种数组或列表。而在这种情况下,继承方法将完全中断。

当对像这样代表现实世界概念的对象进行建模时,首先要考虑对这些现实世界概念的直觉,其次要考虑实现的技术捷径。如果它在建模的内容方面没有意义,那么它在代码中也没有意义。

于 2012-08-14T15:46:47.500 回答
3

继承意味着“is-a”关系,而指针意味着“has-a”关系。

老师是实验室吗?老师是一门学科吗?不,它有一个主题,它有一个实验室,所以这是一个“有”的关系。因此,在这种情况下,您应该使用指针。

当您尝试更改老师的实验室时,为什么继承不起作用会变得很明显。您可以轻松地更改指针指向的对象,但是替换基类的所有数据要麻烦得多。

举一个使用继承的例子,EnglishTeacher 可以继承 Teacher,因为它也是一个教师,但具有额外的能力。

于 2012-08-14T15:44:04.180 回答
3

考虑一下“is-a”(用于继承)和“has-a”(用于聚合)关系在您提出的解决方案中是否有意义

ATeacher既不是 aLab也不是 a Subject- 我认为您应该使用聚合解决方案。

但是,在开始编写代码之前,您真正需要完全排序的是您的数据模型。您需要识别对象之间的关系和多样性(即一对一、一对多等)。

于 2012-08-14T15:41:20.213 回答
1

采取常识的方法:

继承表达了一种is-a关系。老师显然既不是a也不是Subjecta Lab,这将是一个严重的提眉。所以我会说聚合 (a has-aor has-many) 是要走的路。

您还需要决定是使用值语义还是引用语义。这意味着相等性将是程序中对象的实际相等性,或者相等性可以通过对象的某些部分进行计算。

如果您使用引用语义,您将需要确保您使用的是智能指针或其他形式的内存管理,否则事情会很快变得丑陋。

于 2012-08-14T15:42:06.547 回答
1

当您继承一个类时,就像在上一个示例中一样,将其视为扩展该类现有的已定义行为。那么,在这种情况下,问自己一个问题:“老师”是否提高了“实验室”的能力?对我来说,答案很明确——它们不是——它们是完全不同的对象,因此继承并不是在问题域中对这些元素进行建模的理想方式。一个老师一个班级,一个班级一个科目,等等——因此,聚合似乎是一条更好的路径。

于 2012-08-14T15:45:57.907 回答
0

如果您查看此示例,您将理解这个概念:

void doExperimentsIn( Lab &room ){...}

如果您从 派生TeacherLab您也可以在 a 中进行实验Teacher。(这很愚蠢。)

于 2012-08-14T15:59:28.433 回答