简体   繁体   English

如何解决具有多个派生类的抽象基类的继承

[英]How to resolve inheritance of abstract base class with multiple derived classes

I want to use an abstract base class for the purpose of interfacing and usability. 我想使用抽象基类来实现接口和可用性。 This abstract base class will be used as the parent class for several different derived classes, each of which has need of a certain subset of the pure virtual functions in the abstract base class. 该抽象基类将用作几个不同派生类的父类,每个派生类都需要抽象基类中纯虚函数的某个子集。 An outline of my scheme is as follows. 我的计划概述如下。

abstractclass.hpp abstractclass.hpp

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

derivedclass1.hpp derivedclass1.hpp

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

derivedclass2.hpp derivedclass2.hpp

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

derivedclass3.hpp derivedclass3.hpp

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

Given the current implementation, all of the above classes are abstract classes and no objects can be created from these classes. 在当前实现的情况下,以上所有类都是抽象类,无法从这些类中创建任何对象。 In the past, I have resolved this issue with preprocesser directives around each virtual function. 过去,我已经通过围绕每个虚拟函数的预处理器指令解决了此问题。

abstractclass.hpp abstractclass.hpp

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

And at the top of each derived class's header file, before the include to abstractclass.hpp I would write something like the following 在每个派生类的头文件的顶部,在abstractclass.hpp的include之前,我将编写以下内容

derivedclass1.hpp derivedclass1.hpp

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

This worked when I was working with small projects and not writing make files. 当我处理小型项目而不编写make文件时,此方法有效。 The header for the abstract class was effectively altered based on which derived class was using it, so long as I kept my directives in the correct place. 只要我的指令放在正确的位置,就可以根据使用哪个派生类有效地更改了抽象类的头。 Now that I am using makefiles, this does not work. 现在,我正在使用makefile,这不起作用。 abstractcalss.cpp is compiled without any of the virtual functions in the header file because it is compiled separately from the derivedclass. 由于在与头文件分开编译的情况下,abstractcalss.cpp的编译没有头文件中的任何虚拟函数。 I am looking for a good workaround for this. 我正在为此寻找一个好的解决方法。

I want this functionality because I have many similar derived classes from this abstract base class that are used by a variety of other tools I have written. 我想要此功能,因为我有很多类似的派生类,这些派生类都来自于该抽象基类,并由我编写的各种其他工具使用。 I want to keep these other tools as simple as possible and just use pointers to the abstract class instead of writing template classes for everything. 我想使这些其他工具尽可能简单,只使用指向抽象类的指针,而不是为所有内容编写模板类。

--Further information I have a situation where AbstractClass is in a has-a relationship with SubAbstractClass and is implemented by use of having a pointer to SubAbstractClass in AbstractClass. -更多信息我遇到这样的情况,AbstractClass与SubAbstractClass处于has-a关系,并且通过使用指向AbstractClass中的SubAbstractClass的指针来实现。 Furthermore, for each of the derived classes there is a similar has-a relationship with SubDerivedClass1, SubDerivedClass2, … I don't want to write containers for every new class that I create, especially because I can combine my derived classes to create novel classes that are important and functional and any such combination of new classes would require creating the appropriate set of subclasses. 此外,对于每个派生类,与SubDerivedClass1,SubDerivedClass2都有类似的关系。。。我不想为我创建的每个新类编写容器,尤其是因为我可以将派生类组合在一起以创建新颖的类重要且实用的功能,新类的任何此类组合都需要创建适当的子类集。 To this end, it is useful to have an ABC to allow the pointers to be declared once and work for any derived class. 为此,使用ABC允许一次声明指针并适用于任何派生类非常有用。

[...] several different derived classes, each of which has need of a certain subset of the pure virtual functions in the abstract base class. 几个不同的派生类,每个派生类都需要抽象基类中的纯虚函数的某个子集。

Obviously, this won't work. 显然,这是行不通的。 Moreover, your attempts to make things simpler are, in my opinion, having the opposite effect. 而且,在我看来,您尝试使事情变得简单的做法却产生了相反的效果。 You are making things much more complex by introducing preprocessor black magic to comment-in and comment-out specific parts of the interfaces. 通过引入预处理器黑魔法来注释和注释掉接口的特定部分,您使事情变得更加复杂。

You're swimming upstream without a paddle here. 您在这里没有桨的上游游泳。 Instead of having one interface class to which you add and remove methods piecemeal, just develop several different interface classes that do a better job of modularizing the functionality: 不用零散地添加和删除方法的一个接口类,而只是开发几个不同的接口类,它们可以更好地对功能进行模块化:

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

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

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

Trying to make one universal, God class that you blow pieces off of to suit specific modules's needs is going to eventually bite you, and hard. 试图使一个通用的上帝课程,您为了满足特定模块的需要而放弃,最终将使您难以忍受。 Consider what might happen when you need two instantiations of the interface in the same translation unit, but each of those instantiations have different pieced #define ed in. Sounds like a nightmare to me. 考虑在同一翻译单元中需要接口的两个实例化,但是每个实例化都有不同的#define时,会发生什么。听起来对我来说就像一场噩梦。

Start with a common base class. 从一个通用的基类开始。

class AbstractBaseClass {
  // common stuff goes here
};

Then, create abstract interfaces for the sub-versions: 然后,为子版本创建抽象接口:

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

which contain the abstract pureVirt methods. 其中包含抽象的pureVirt方法。

Finally, derive your implementation classes form the sub classes: 最后,从子类派生实现类:

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
};

now, objects that know you are a particular sub class can access the pureVirtX member. 现在, 知道您是特定子类的对象可以访问pureVirtX成员。 Those that don't only have access to the common AbstractBaseClass interface (whatever that is - you mention that some code doesn't need to know about these particular virtual methods). 那些不仅可以访问公共AbstractBaseClass接口的控件(无论如何-您提到的某些代码不需要了解这些特定的virtual方法)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否将继承的基类复制到派生类? - Are base classes in inheritance copied to the derived class? 钻石 inheritance 中的虚拟类,在基础 class 和大多数派生 class 之间有多个类 - Virtual classes in diamond inheritance with multiple classes in between base class and most derived class 在多继承方案中使用虚拟基类时,是否所有派生类都必须引用虚拟基? - When using a virtual base class in a multiple inheritance scenario, is it necessary for all derived classes to reference the virtual base? 使用多重继承来满足抽象基类 - Use multiple inheritance to satisfy abstract base class 难以实现类型抽象基 class 的 C++ 数组,同时其中有多个不同的派生类 - Difficulty implement a C++ array of type abstract base class while having multiple different derived classes in it 从具有多重继承的派生类中调用所有基类的通用命名方法 - Call a common named method of all base classes from a derived class with multiple inheritance OOP-抽象类类型,在基类和派生类中初始化变量 - OOP - abstract class types, initializing variables in base and derived classes 抽象基类,私有继承和多重公共继承 - Abstract Base Class, private inheritance and multiple public inheritance 抽象基类的模糊继承: - Ambiguous inheritance of abstract base classes: 继承:基类的模板容器,其中包含派生类的实例 - Inheritance: A template container of base class containing instances of derived classes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM