Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:条件继承可能吗_C++_Inheritance_Arduino - Fatal编程技术网

C++ C++;:条件继承可能吗

C++ C++;:条件继承可能吗,c++,inheritance,arduino,C++,Inheritance,Arduino,我在做一个微处理器(Arduino)项目。我的库Foo继承自现有库Basic。后来我将Basic的功能扩展到另一个类Advanced。然而,Advanced更难扩展硬件,使得已经制作的演示之一无法使用 我的想法如下: class Foo: #ifndef USE_BASIC public Advanced #else public Basic #endif { ... } 并在我的演示代码中放入#define USE_BASIC: #define USE_BASIC #include <

我在做一个微处理器(Arduino)项目。我的库
Foo
继承自现有库
Basic
。后来我将
Basic
的功能扩展到另一个类
Advanced
。然而,
Advanced
更难扩展硬件,使得已经制作的演示之一无法使用

我的想法如下:

class Foo:
#ifndef USE_BASIC
public Advanced
#else
public Basic
#endif
{
...
}
并在我的演示代码中放入
#define USE_BASIC

#define USE_BASIC
#include <Foo.h>
#定义使用基本
#包括

但是,Foo不是从Basic继承的。我做错了吗?或者,如果有其他方法可以解决这个问题?

另一个解决方案是避免继承,并使用这样的模式提供更大的灵活性。因此,您可以在运行时将Foo的行为从
Basic
更改为
Advanced

这是库供应商经常面临的一个基本配置问题。对于小型项目,只要在适当的情况下,在
foo.h
标题中定义
使用_BASIC
。对于具有大量配置选项的大型项目,您可能希望转到一个配置文件,该文件在每个库头中获取
#包括
d,并在其中定义适当的内容。在这种情况下,我将在配置头中进行所有选择:

// uncomment to use `Basic` throughout:
// #define USE_BASIC
#ifdef USE_BASIC
typedef Basic FooBase;
#else
typedef Advanced FooBase;
#endif

一些人提出了模式策略。 如果选择在编译时进行,则最好使用基于策略的设计:

这与您的设计大致相同,但您使用的是模板:

template <class Base> class YourClass : public base {
    ...
};
模板类YourClass:public base{
...
};
使用时:

#ifdef BASIC
typedef YourFinalClass Yourclass<Basic>;
#else
typedef YourFinalClass Yourclass<Advanced>;
#endif
#ifdef BASIC
键入def yourlfinalclass yourlclass;
#否则
键入def yourlfinalclass yourlclass;
#恩迪夫

一个更干净的解决方案是使用模板:让编译器根据模板参数选择基类

以下是一个例子:

 #include <type_traits> //for std::conditional


 //here you go with your own class
 template<bool UseAdvanced>
 class Foo : public std::conditional<UseAdvanced, Advanced, Basic>::type
 {
      //your code
 };

希望这能有所帮助。

\include
指令之前,您必须在每个包含
Foo.h
的翻译单元(.cpp+包含的标题)中定义
使用
。考虑使用编译器开关(在每个翻译单元中自动声明<代码> UsIsBasic < /C>),或者在标题中放置<代码>定义> /COD>。标题没有什么特别的,OP显示了在包含标题之前定义
USE_BASIC
的示例。编译器是在cpp上运行的,因此预处理器先看到define,然后包含header(在OP的示例中)。我无法理解-1。如果内存有限或间接寻址对性能影响太大,这可能不可能。谢谢!了解这些方法很好,但可能不适合我的情况,不确定在微处理器中添加模板是否会带来更多好处或坏处…@XunYang:你在说什么“微处理器”?你是说预处理器吗?如果是的话,那么你就不需要在模板中使用预处理器。不,它在Arduino上,所以这是一种嵌入式处理器system@XunYang:我不认为模板会在Arduino中引起任何问题,因为一旦类模板被实例化,它就和任何其他普通类一样。模板不是Arduino编译器的默认语言功能,所以我需要引入另一个第三方库来使用模板,这将占用更多已经达到极限的存储空间。。。也许值得一试,下一个项目:)我肯定你是指
typedef基本FooBase
typedef FooBase Basic与其他typedef相同。@Nawaz-是的,谢谢。我不知道我怎么做了这么愚蠢的事。固定的。
Foo<true>   fooWithAdvanced; //it uses Advanced as base class
Foo<false>  fooWithBasic;    //it uses Basic as base class!
 template<typename Base>
 class Foo : public Base
 {
      //your code
 };
 Foo<Advanced>  fooWithAdvanced;
 Foo<Basic>     fooWithBasic;
 Foo<OtherBase> fooWithOtherBase;