【问题标题】:Does multi-layer inheritance make sense in C++?多层继承在 C++ 中有意义吗?
【发布时间】:2014-03-04 15:45:30
【问题描述】:

下面我使用3层继承设计:

class connect_info {
  // these members
};

class vertex : public connect_info {
  // ...
};

// user-defined struct
class algo_vertex: public vertex {
  // ...
};

connect_info 类的成员(我在这个问题中称之为these members)仅用于vertex 类。但为了保持vertex 类的语义清晰,我必须将these members 与另一个基类(connect_info) 分开。

问题在这里产生:

  1. 如何从用户定义的类中隐藏这些成员? (protectedprivate现在都没有用了,如果没有connect_info基类,private可以正常工作)
  2. 多层继承设计在任何情况下都有意义吗?
  3. 虚拟解构函数在多层继承情况下能否正常工作?

【问题讨论】:

  • 1) 那就不要公开继承 2) 当然
  • 不要使用private继承。让事情变得更简单。同样,这取决于您希望如何构建代码。

标签: c++ class oop inheritance multiple-inheritance


【解决方案1】:

这里的一个很好的权衡是从connect_info 私下创建vertexinherit。与组合的最大区别在于,在vertex 类中,您可以认为自己是connect_info,这意味着您可以通过this->member 而不是connect_info_attribute.member 来访问these members。此外,您不需要任何 friend 或封装技巧。

总而言之,从子类的角度来看,private 继承意味着我认为自己是“父母”,但我不希望其他人(甚至我的孩子)认为我是一个“父母” .

【讨论】:

    【解决方案2】:

    继承在类之间引入了强耦合,通常会被避免。相反,人们正在使用组合。阅读Prefer composition over inheritance问答。

    在您的具体示例中,当您添加 algo_B_vertex 类时,您会做什么,其中来自 Vertex 的某些字段和方法毫无意义。或者在更糟糕的情况下connect_info。然后你会遇到各种各样的问题。更不用说多层继承的复杂性了。

    如何从用户定义的类中隐藏这些成员?

    通过使用组合,并在私有部分中创建对象。

    多层继承设计在任何情况下都有意义吗?

    当然可以。幸运的是,这种情况的数量很少。一般建议是在进入多重继承之前三思而后行。

    【讨论】:

      【解决方案3】:

      您可能需要移动到has-a 关系,其中connect_info 可以是内部class(类内的类)并使其成为private,如果您想在@987654326 中隐藏connect_info 成员@。

      class vertex {
        // ...
        private:
           class connect_info{/*these members*/};
      };
      
      class algo_vertex : public vertex{ 
        // connect_info members no longer accessible,
        // unless you provide member functions in `vertex` to access it.
      };
      

      【讨论】:

      • 这种情况下内部类和私有继承有什么区别?
      • 保持简单是@xunzhang 的理念,您可以更好地控制谁可以使用connect_info 类中的内容。
      • @xunzhang 区别也是语义上的(如果我正确阅读了您的问题,这似乎是您的兴趣):顶点是否有 connect_info 成员或者顶点是 connect_info 的专用版本?当“A 是 B 的特殊版本”没有意义时,不要使用继承。
      • @Aniket 带有内部类,我该如何使用这些成员?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 2016-08-09
      • 2011-06-16
      相关资源
      最近更新 更多