我想使用抽象基类来实现接口和可用性。此抽象基类将用作几个不同派生类的父类,每个派生类都需要抽象基类中的纯虚函数的某个子集。我的计划概要如下。
abstractclass.hpp
AbstractClass{
/* Declaration */
void pureVirt1() = 0;
void pureVirt2() = 0;
void pureVirt3() = 0;
};
derivedclass1.hpp
DerivedClass1{
/* Declaration */
void pureVirt1();
};
derivedclass2.hpp
DerivedClass2{
/* Declaration */
void pureVirt2();
};
derivedclass3.hpp
DerivedClass3{
/* Declaration */
void pureVirt3();
};
鉴于当前的实现,所有上述类都是抽象类,并且不能从这些类创建任何对象。在过去,我已经使用围绕每个虚函数的preprocesser指令解决了这个问题。
abstractclass.hpp
AbstractClass{
#ifdef _1
void purVirt1()=0;
#endif
...
在每个派生类的头文件的顶部,在include到abstractclass.hpp之前,我会写下面的内容
derivedclass1.hpp
#define _1
#include"abstractclass.hpp"
...
当我处理小项目而不是编写make文件时,这很有用。只要我将指令保存在正确的位置,抽象类的标题就会根据派生类使用它而有效地更改。现在我正在使用makefile,这不起作用。 abstractcalss.cpp是在头文件中没有任何虚函数的情况下编译的,因为它是与derivedclass分开编译的。我正在为此寻找一个好的解决方法。
我想要这个功能,因为我有许多来自这个抽象基类的类似派生类,我已经编写过各种其他工具。我想让这些其他工具尽可能简单,只需使用指向抽象类的指针,而不是为所有内容编写模板类。
- 更多信息 我有一种情况,AbstractClass与SubAbstractClass有一个has-a关系,并通过在AbstractClass中使用指向SubAbstractClass的指针来实现。此外,对于每个派生类,与SubDerivedClass1,SubDerivedClass2有一个类似的has-a关系......我不想为我创建的每个新类编写容器,特别是因为我可以组合我的派生类来创建新类这是重要的和功能性的,任何这种新类的组合都需要创建适当的子类集。为此,有一个ABC允许指针声明一次并适用于任何派生类是很有用的。
答案 0 :(得分:1)
[...]几个不同的派生类,每个派生类都需要一个 抽象基础中的纯虚函数的某个子集 类。
显然,这不起作用。此外,在我看来,你使事情更简单的尝试具有相反的效果。通过引入预处理器黑魔法来评论和注释掉接口的特定部分,你会使事情变得更加复杂。
你在没有桨的情况下向上游游泳。您可以开发几个不同的接口类,以便更好地模块化功能,而不是使用一个接口类来添加和删除方法:
AbstractClass1{
/* Declaration */
void pureVirt1() = 0;
};
AbstractClass2{
/* Declaration */
void pureVirt2() = 0;
};
AbstractClass3{
/* Declaration */
void pureVirt3() = 0;
};
试图制作一个普遍的,上帝的课程,你吹掉的部分,以满足特定模块的需要,最终会咬你,而且很难。考虑当您需要在同一个翻译单元中进行两个接口实例时可能会发生什么,但每个实例都有不同的拼合#define
。对我来说,这听起来像是一场噩梦。
答案 1 :(得分: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
方法)。