【问题标题】:Which one is better, pointer to other class or inherit from that class哪个更好,指向其他类或从该类继承
【发布时间】:2012-08-10 22:54:33
【问题描述】:

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

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

我在 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++”,但它们只给出了一些简单的例子 :)

【问题讨论】:

  • 从逻辑上讲,老师应该知道Lab和Subject,但他不能从Lab或Subject中派生出来

标签: c++ class inheritance pointers


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    采取常识的方法:

    继承表示is-a 关系。明明是老师 既不是Subject 也不是Lab,这将是一个严肃的眉毛 提高者。所以我会说聚合(has-ahas-many)是 去吧。

    您还需要确定是否使用值语义 或参考语义。这意味着平等将是真正的平等 程序中的对象或相等性可以通过某些计算 对象的一部分。

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

    【讨论】:

    • 由于不止一个老师可以教一个给定的学科,你不能很好地使用价值语义。教师不以任何方式拥有这些科目;这里没有什么可以推荐使用我所知道的任何类型的智能指针。
    • @JamesKanze 如果平等就是价值平等,那么一门学科的教师人数如何?对于智能指针:为什么 shared_ptr/weak_ptr 不能在这里工作?
    • 如果Subject 具有值语义,那么就没有问题(也不需要指针)。在 OO 设计中,情况可能并非如此。而shared_ptr 肯定行不通;特定的Subject 是否存在与是否有老师教它无关。 (另外,任何时候你需要使用weak_ptr,你还不如完全放弃智能指针,因为分析哪些指针必须是弱的比手动内存管理更复杂。)
    【解决方案3】:

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

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

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

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

    【讨论】:

    • 我不确定“has-a”是否对应。有关系,但仅此而已。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      “优先考虑‘对象组合’而不是‘类继承’。” - Gang of Four

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

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

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

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

      【讨论】:

      • 好的,我知道我应该使用什么以及在哪里使用,但我想到的另一个问题是,让老师教不止一门科目,而不是我如何指出所有科目,如果他再分配一门科目,我应该怎么做.我知道如何使用固定长度的对象,但是当长度变化时,我真的不明白该怎么做..
      • 以及任何能够强化我的 c++ 中的对象指针概念的书。我知道什么是对象、类、继承等术语,但如何扩展我的知识以正确使用它们。
      • @NatwarSingh:如果Teacher 可以拥有(或以某种方式关联)多个Subject,那么我想该类成员将是Subjects 的数组。我不知道 C++ 的细节,但在 C# 中,我会使用 IEnumerable<Subject>IList<Subject> 来表示 Subjects 的列表。
      • @NatwarSingh:如果您使用基本指针,Subject* 可以指向单个Subject,或者它可以指向Subjects 数组中的第一个Subject。您只需要一些成员来说明您正在使用多少。不过,我自己只是为此使用 std::vector<Subject>:一个向量可以包含 0、1 或许多模板类型的对象。
      【解决方案6】:

      如果你看一下这个例子,你就会明白这个概念:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-09
        • 1970-01-01
        • 1970-01-01
        • 2014-04-19
        • 1970-01-01
        • 2016-09-02
        • 1970-01-01
        相关资源
        最近更新 更多