说我有一个接口层次结构:

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是抽象的东西,只有在具有公共功能的实现时才存在。

我该如何设计呢?谢谢。

最佳答案

仅存在接口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可以只是一个独立的实用程序功能?

10-07 15:51