Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: is conditional inheritance possible

I'm working on a micro-processor(Arduino) project. My library Foo is inherited from a existing library Basic. Later I extended the functionalities of Basic, into another class Advanced. However, Advanced stretches the hardware harder, making one of the already made demos unusable.

What I'm thinking about is as following:

class Foo:
#ifndef USE_BASIC
public Advanced
#else
public Basic
#endif
{
...
}

And put #define USE_BASIC in my demo code:

#define USE_BASIC
#include <Foo.h>

However Foo is not inheriting from Basic. Am I doing it wrong here? Or if there're alternatives to solve this problem?

like image 568
Xun Yang Avatar asked May 03 '13 12:05

Xun Yang


People also ask

Is inheritance possible in C?

No, as we know, Inheritance is the property of OOPs i.e. Object-oriented programming. Therefore, there is no compiler-level support for inheritance in C.

Is inheritance possible in C if no then why?

C is not an Object Oriented language. Inheritance is a property of Object Oriented languages. There is no Compiler-level support for inheritance in C.

Which Cannot be inherited in C?

C++ - Constructor & Friend Function Constructor cannot be inherited but a derived class can call the constructor of the base class.


2 Answers

A much more clean solution would be using template : let the compiler choose the base class depending on a template argument.

Here is one example:

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

And here is how you would be using this class:

Foo<true>   fooWithAdvanced; //it uses Advanced as base class
Foo<false>  fooWithBasic;    //it uses Basic as base class!

Well that is one way to do that. But there are better ways. In particular, I would design the class template in the following way, in which the template argument would act as base class. This would be more flexible design.

 template<typename Base>
 class Foo : public Base
 {
      //your code
 };

So you can use Basic, Advanced or any other class as base class, as long as it supports the functionalities as required by Foo and its usage:

 Foo<Advanced>  fooWithAdvanced;
 Foo<Basic>     fooWithBasic;
 Foo<OtherBase> fooWithOtherBase;

Hope that helps.

like image 200
Nawaz Avatar answered Oct 21 '22 05:10

Nawaz


This is a basic configuration problem that library vendors face constantly. For small projects, just #define USE_BASIC, when appropriate, in the foo.h header. For larger projects with lots of configuration options you might want to go to a configuration file that gets #included in every library header and define appropriate things there. In that case, I'd do all of the selection in the configuration header:

// uncomment to use `Basic` throughout:
// #define USE_BASIC
#ifdef USE_BASIC
typedef Basic FooBase;
#else
typedef Advanced FooBase;
#endif
like image 35
Pete Becker Avatar answered Oct 21 '22 06:10

Pete Becker