1

我想使用抽象基类来实现接口和可用性。这个抽象基类将用作几个不同派生类的父类,每个派生类都需要抽象基类中纯虚函数的某个子集。我的方案大纲如下。

抽象类.hpp

AbstractClass{
/* Declaration */
void pureVirt1() = 0;
void pureVirt2() = 0;
void pureVirt3() = 0;
};

派生类1.hpp

DerivedClass1{
/* Declaration */
void pureVirt1();
};

派生类2.hpp

DerivedClass2{
/* Declaration */
void pureVirt2();
};

派生类3.hpp

DerivedClass3{
/* Declaration */
void pureVirt3();
};

鉴于当前的实现,上述所有类都是抽象类,不能从这些类创建对象。过去,我已经通过围绕每个虚拟函数的预处理器指令解决了这个问题。

抽象类.hpp

AbstractClass{
#ifdef _1
void purVirt1()=0;
#endif
...

在每个派生类的头文件的顶部,在包含到 abstractclass.hpp 之前,我会写如下内容

派生类1.hpp

#define _1
#include"abstractclass.hpp"
...

当我处理小项目而不是编写 make 文件时,这很有效。只要我将指令保存在正确的位置,抽象类的标头就会根据使用它的派生类有效地进行更改。现在我正在使用makefile,这不起作用。abstractcalss.cpp 编译时没有头文件中的任何虚函数,因为它是与派生类分开编译的。我正在为此寻找一个好的解决方法。

我想要这个功能,因为我有许多来自这个抽象基类的类似派生类,这些派生类被我编写的各种其他工具使用。我想让这些其他工具尽可能简单,只使用指向抽象类的指针,而不是为所有东西编写模板类。

--更多信息 我有一种情况,AbstractClass 与 SubAbstractClass 存在关联关系,并且是通过在 AbstractClass 中使用指向 SubAbstractClass 的指针来实现的。此外,对于每个派生类,都存在与 SubDerivedClass1、SubDerivedClass2 类似的 has-a 关系……我不想为我创建的每个新类编写容器,特别是因为我可以组合我的派生类来创建新类重要且实用的新类的任何此类组合都需要创建适当的子类集。为此,有一个 ABC 以允许指针被声明一次并适用于任何派生类是很有用的。

4

2 回答 2

1

[...] 几个不同的派生类,每个派生类都需要抽象基类中纯虚函数的某个子集。

显然,这是行不通的。此外,在我看来,你试图让事情变得更简单的尝试会产生相反的效果。通过引入预处理器黑魔法来注释和注释接口的特定部分,您正在使事情变得更加复杂。

你在这里没有桨就逆流而上。无需使用一个接口类来零碎地添加和删除方法,只需开发几个不同的接口类,它们可以更好地模块化功能:

AbstractClass1{
/* Declaration */
void pureVirt1() = 0;
};

AbstractClass2{
/* Declaration */
void pureVirt2() = 0;
};

AbstractClass3{
/* Declaration */
void pureVirt3() = 0;
};

试图制作一个通用的、上帝的类,你可以把它吹掉以适应特定模块的需求,最终会咬你一口,而且很难。考虑一下当您在同一个翻译单元中需要接口的两个实例化时可能会发生什么,但每个实例化都有不同的拼凑而成#define。对我来说听起来像是一场噩梦。

于 2013-06-28T18:38:42.580 回答
0

从一个通用的基类开始。

class AbstractBaseClass {
  // common stuff goes here
};

然后,为子版本创建抽象接口:

class AbstractSubClass1:public AbstractBaseClass {
public:
  void pureVirt1() = 0;
};
class AbstractSubClass2:public AbstractBaseClass {
public:
  void pureVirt2() = 0;
};
class AbstractSubClass3:public AbstractBaseClass {
public:
  void pureVirt3() = 0;
};

其中包含抽象pureVirt方法。

最后,从子类派生您的实现类:

class Derived1 : public AbstractSubClass1 {
  virtual void pureVirt1() override; // override if your compiler supports it
};
class Derived2 : public AbstractSubClass2 {
  virtual void pureVirt2() override; // override if your compiler supports it
};
class Derived3 : public AbstractSubClass3 {
  virtual void pureVirt3() override; // override if your compiler supports it
};

现在,知道您是特定子类的对象可以访问该pureVirtX成员。那些不仅可以访问公共AbstractBaseClass接口的人(无论如何 - 你提到某些代码不需要了解这些特定virtual方法)。

于 2013-06-28T18:59:40.647 回答