【问题标题】:What's the best style of Inheriting from two brothers in C++?在 C++ 中继承两个兄弟的最佳风格是什么?
【发布时间】:2021-09-22 03:24:49
【问题描述】:

我需要实现几个模块,如下所示,

#include <stdio.h>
class Base{
protected:
    int data;
};
class ModeA : public Base{};
class ModeB : public Base{};
class ModeHybrid: public ModeA, public ModeB{
public:
    void func(){printf("%d\n", this->data);}
};

int main(){
    ModeHybrid mh;
    mh.func();
}

在哪里,

  • 有一个类'Base'
  • 两个模块“ModeA”和“ModeB”继承自“Base”
  • 混合模块“ModeHybrid”继承自“ModeA”和“ModeB”

但是,成员变量“data”将被复制,因为“ModeHybrid”继承自“ModeA”和“ModeB”。

有什么办法可以避免吗?

【问题讨论】:

  • 查找“虚拟继承”

标签: c++ inheritance multiple-inheritance


【解决方案1】:

至少有三种方法可以解决此问题。

第一个是virtual继承,它有开销。在里面,你只有一个Base

class ModeA : public virtual Base{};
class ModeB : public virtual Base{};

这确实意味着您实例化的派生最多的类必须构造Base

另一种方法是基于模板的,您可以在其中传入希望父级派生的类。

class Base{
protected:
    int data;
};
template<class B=Base>
class ModeA : public B{};
template<class B=Base>
class ModeB : public B{};
class ModeHybrid:
  public ModeA<ModeB<Base>>
{
public:
    void func(){printf("%d\n", this->data);}
};

另一种方法是将数据填充到其他位置,并使用getData() 方法使Base 成为抽象接口。

class Base{
protected:
    int readData() const = 0;
    int& writeData() = 0;
};
class ModeA : public Base{};
class ModeB : public Base{};
class ModeHybrid:
  public ModeA, public ModeB
{
public:
    void func(){printf("%d\n", this->readData());}
};
template<class X>
struct ImplementBase:X {
  int data;
  int readData() const final { return data; }
  int& writeData() final { return data; }
};

ImplementBase<ModeHybrid> hybrid;

这个版本在其层次结构中有两个Base 类,但我们并不关心。数据存在于ImplementBase

【讨论】:

    【解决方案2】:

    这是多重继承中的菱形问题。解决方法是使用virtual

    class ModeA : virtual public Base{};
    class ModeB : virtual public Base{};
    

    【讨论】:

      猜你喜欢
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 2019-08-04
      • 2015-03-13
      • 2020-01-02
      • 1970-01-01
      • 2018-08-16
      • 1970-01-01
      相关资源
      最近更新 更多