正确实现类层次结构

时间:2015-03-12 16:56:11

标签: c++ class inheritance interface implementation

假设我有一个界面层次结构:

class A
{
   virtual void commonFunc() = 0;
};

class B1 : public A
{
   virtual void b1SpecificFunc() = 0;
};

class B2 : public A
{
   virtual void b2SpecificFunc() = 0;
};

仅存在接口A以避免重复commonFunc()函数。

现在,如果我想实现这个,以便有2个可实现的类ImplB1和ImplB2,我可以这样做:

class ImplA
{
   virtual void commonFunc();
};

class ImplB1 : public ImplA
{
   virtual void b1SpecificFunc();
};

class ImplB2 : public ImplA
{
   virtual void b2SpecificFunc();
};

这个问题是它让ImplA变得不稳定,我不想这样做。我只希望ImplB1和ImplB2是可实现的,因为ImplA只是存在共同功能的共同点。

我怎么能这样设计呢?谢谢。

2 个答案:

答案 0 :(得分:2)

  

仅存在接口A以避免重复commonFunc()函数。

你的意思是避免重复声明,不是吗?

class ImplA
{
   virtual void commonFunc();
};

这应该是:

class ImplA : public A
{
   virtual void commonFunc();
};

我想重点是ImplA实际上有commonFunc的实现。所以为了这个答案的简洁,让我们把它放到课堂定义中:

class ImplA : public A
{
   virtual void commonFunc() {} // implementation
};
  

这个问题是它让ImplA变得不稳定。

只需将ImplA的析构函数设为纯虚拟:

class ImplA : public A
{
public:
   virtual ~ImplA() = 0 {}

private:
   virtual void commonFunc() {}
};

即使在派生类内也会阻止实例化。功能。例如,以下内容将创建编译器错误:

class ImplB1 : public ImplA
{
public:
   virtual void b1SpecificFunc()
   {
       ImplA a; // error, cannot instantiate abstract class
   }
};

实际上,您甚至无法在自己的函数中实例化该类:

class ImplA : public A
{
public:
   virtual ~ImplA() = 0 {}

private:
   virtual void commonFunc()
   {
       ImplA a; // error, cannot instantiate abstract class
   }
};

但严重的是,这一切似乎都非常过度设计。也许您真正需要的是使commonFunc成为A的非虚拟保护函数,派生类可以在需要时调用它们。

或许commonFunc可能只是一个独立的效用函数

答案 1 :(得分:0)

您可以执行以下操作。此外,这里有一个SO question/answer

注意:当我回答你可以做到这一点的问题时我并没有断言你应该做什么。< / p>

代码

#include <iostream>

class A
{
public:
    virtual void commonFunc() = 0;
};


void A::commonFunc() // Pure virtual but implemented anyway
{
    // Derived classes can explicitly opt-in to this implementation
    std::cout << "A::commonFunc()\n";
}

class B1 : public A
{
public:
    virtual void b1SpecificFunc() = 0;
};

class B2 : public A
{
    virtual void b2SpecificFunc() = 0;
};

class ImplB1 : public B1
{
public:
    // This function must be implemented because its declared pure virtual
    virtual void commonFunc()
    {
        // Can override the behavior if desired...
        A::commonFunc(); // Explicitly use default implementation
    }

    virtual void b1SpecificFunc()
    {
        std::cout << "b1SpecificFunc()\n";
    }
};

class ImplB2 : public B2
{
public:
    // This function must be implemented because its declared pure virtual
    virtual void commonFunc()
    {
        // Can override the behavior if desired...
        A::commonFunc(); // Explicitly use default implementation
    }

    virtual void b2SpecificFunc()
    {
        std::cout << "b2SpecificFunc()\n";
    }
};

int main()
{
    //A a; // Won't compile (as expected/desired)
    ImplB1 b1;
    ImplB2 b2;

    b1.commonFunc();
    b1.b1SpecificFunc();

    b2.commonFunc();
    b2.b2SpecificFunc();

    return 0;
}

输出

A::commonFunc()
b1SpecificFunc()
A::commonFunc()
b2SpecificFunc()