虚拟继承和接口

时间:2012-06-26 10:20:39

标签: c++ virtual-inheritance

class IA
{
public:
    virtual void a() = 0;
};

class A: virtual public IA
{
public:
    virtual void a()
    {
    }
};

class IB: virtual public IA
{
public:
    virtual void b() = 0;
};

class B: virtual public IB, public A
{
public:
    virtual void b()
    {
    }
};

你是否总是像我一样继承你的界面虚拟?如果没有,您将如何强制执行上述代码?

2 个答案:

答案 0 :(得分:2)

有一个相对干净的解决方法。当您从 IB 继承 B 时,编译器要求您提供 IB 中所有抽象方法的实现,包括 IA 。由于a()已经在 A 中实施,您可以在 B 中创建一个简单地从 A 调用方法:

class IA
{
public:
    virtual void a() = 0;
};

class A: public IA
{
public:
    virtual void a()
    {
    }
};

class IB: public IA
{
public:
    virtual void b() = 0;
};

class B: public IB, public A
{
public:
    virtual void b()
    {
    }

    virtual void a()
    {
        A::a();
    }
};

答案 1 :(得分:2)

在分离接口和实现层次结构时,使用多重继承虚拟继承相结合是一种合适的设计选择。例如,见: " When virtual inheritance IS a good design?"

优点:

  • 减少代码重复:界面实现可重复使用
  • 在类的接口实现之间切换很容易
  • 只是看基类讲述了很多具体的实现

缺点:

  • 由虚拟继承引发的调度性能
  • 不常见的模式,需要为外部/新人解释/记录

备选方案:

  • 如果需要界面层次结构,没有好的选择

  • 否则,层次结构可以分解为单个接口

它可能看起来像:

struct IA
{
    virtual ~IA() = default;
    virtual void a() = 0;
};

struct A: public IA
{
    virtual ~A() = default;
    virtual void a() {}
};

struct IB
{
    virtual ~IB() = default;
    virtual void b() = 0;
};

struct B: public IB
{
    virtual ~B() = default;
    virtual void b() {}
};

struct C: public A, public B
{
};