C++ 在C+中理解OOP和多重继承的良好习惯+;

C++ 在C+中理解OOP和多重继承的良好习惯+;,c++,class,oop,inheritance,C++,Class,Oop,Inheritance,我最近了解到,我没有在OOP中练习最好的习惯,而是开始学习更好的OOP习惯。所以我的问题是-我应该限制一个类继承多少东西到一定数量吗 有助于解释的示例 注意:从示例中删除构造函数和析构函数以节省空间 class Object { protected: /* common declarations */ public: /* common functions */ } class Collidable { protected: /* common declarat

我最近了解到,我没有在OOP中练习最好的习惯,而是开始学习更好的OOP习惯。所以我的问题是-我应该限制一个类继承多少东西到一定数量吗

有助于解释的示例

注意:从示例中删除构造函数和析构函数以节省空间

class Object
{
 protected:
    /* common declarations */

 public:
    /* common functions */
}

class Collidable
{
 protected:
    /* common declarations */

 public:
    virtual void Collide() = 0;

    /* common functions */
}

class Animated
{
 protected:
    /* common declarations */

 public:
    virtual void Animate() = 0;

    /* common functions */
}

class Unit : public Object,  public Collidable, public Animated
{
 protected:
    /* common declarations */

 public:
    virtual void Collide() { /* Collide  */ }
    virtual void Animate() { /* Animate  */ }

    /* common functions */
}
在这里,
class Unit
继承了它上面的三个类,我想知道的是,继承东西时应该限制多少?就像在,
class对象中一样:class,class,class。。。etc
。继承类的数量是否应该限制在一个较小的数量上,并且在继承类之间创建已经继承了一些抽象基类的类?我知道这个问题有点难回答,但我希望保持良好的习惯,如果可以的话,我感谢你的帮助


此外,对于OOP中良好习惯的任何其他建议,我们也将不胜感激。

以下是我关于类层次结构的两点建议:

  • 为可能出现在两个不同类中的每个虚拟函数定义一个接口类肯定不是一个好主意。这些虚拟函数声明通常应该保留在主继承树中,除非您有充分的理由将它们排除在外

    这通常意味着您只有一个类可从中继承,但有时可能会得到两个甚至三个基类。不要完全避免多重继承,它可能是解决一些棘手情况的一个很好的工具,但要尽量减少它的使用

  • 也要避免深层继承层次结构。它们往往通过有效地将类定义跨多个不同的头文件进行拆分来混淆接口,迫使您阅读所有直接和间接的基类声明,以了解类可以做什么

  • 另一个可能出现的问题是,您得到了太多的通用类,这导致类之间的相互作用过于复杂。类应该分组到连接良好的集群/模块中,只有一个非常小的接口从集群外部使用

    在这方面,模块的工作方式有点类似于类之上的另一种封装方式,它允许您筛选公开的类。模块在C++中是非正式的。它们可能对应于源代码树中的目录,但这既不是模块的要求,也不是目录包含模块的良好提示。但是很好地记录您的模块是一个好主意

  • 但是,最重要的是,每个类都应该提供一个清晰简洁的接口,该接口在使用它的客户机代码中尽可能有用。它应该完成一项任务,并且把它做好。如果类需要做复杂的事情,它可以在幕后使用其他类(作为模块的代理),但是它的接口应该尽可能简单


  • 问题是:除了颠覆类型检查器(这是一件坏事)的能力之外,这么多的继承为您带来了什么?特别是,
    对象
    基类的用途是什么?很难回答,因为你的问题太“不是来自我们的宇宙”。例如,我有一个名为“x”的“Collible”,并告诉它“x.Collide()”。这意味着什么?@KonradRudolph:a
    对象
    基类的目的是为所有派生类提供基本功能。这是在数字上完成的,这是一个可怕的想法。C#和Java需要它,不是因为它们的基本功能,而是因为它们的类型系统过去基本上与非泛型的引用容器绑定在一起。在C++中,由于模板而不是必需的。在基类中提供“基本功能”是一个糟糕的想法:任意类型不共享功能。例如,给所有类型一个
    Equals
    方法是不必要的,而且可能容易出错。@Konrad Rudolph-这实际上不是我的问题,但更重要的是,这样做不好吗?那里的代码只是为了在某种程度上说明我的问题的框架。我想知道的是,如果继承这么多基类是一个坏习惯,那么中间是否应该有类来帮助减少继承量,就像上面的例子中那样,我是否应该制作一个
    类CollidableObject:public对象,公共可碰撞的
    还是我应该保持骨架的原样,让
    Unit
    继承所有需要的基类?这当然很有帮助,但为了帮助个人澄清,如果以后使用
    Unit
    继承,我的骨架代码可以吗?(例如
    职业玩家:公共单位
    职业敌人:公共单位
    )或者有更干净、更好的方法吗?非常感谢您的时间和帮助。以后是否使用
    Unit
    进行继承,对它的定义是否正确没有任何影响。您需要回答的问题是:“是否有一个类需要是
    可碰撞的
    ,而不是
    对象
    单元
    ?”如果没有,则将因子
    碰撞()
    转化为
    对象
    单元
    。如果是的话,那就考虑一下。但是试着组装有意义的完整接口类,试着避免用大量琐碎的类淹没类层次结构,比如
    类可碰撞{public:virtual void Collide()=0;}。一两节这样的课是可以的,但不止一把开始发臭。谢谢你,这对我来说现在更有意义了。所以我假设这是任何基类或父类的情况?如果
    Object
    只在
    Unit
    中使用,我最好不要制作
    Object
    并将它的所有函数都放在
    Unit
    中,这取决于组合类的复杂性,但是的,通常最好是采用扁平层次结构。您也可以考虑使用子类(类是