fpllowing предполагает, что вам нужно сохранить BaseInterfaceClass
вместо изменения наследования классов, использующих его (в противном случае возможно просто определить интерфейс для каждой функции и наследовать только те, которые вам нужны).
Вы можете использовать множественное наследование в сочетании со специализированными шаблонами, чтобы получить только те части интерфейса, которые вам нужны:
template<bool B> class FeatureABase {};
template<> class FeatureABase<true> {
public:
virtual void doFeatureA1() = 0;
virtual void doFeatureA2() = 0;
};
//similar definitions for FeatureBBase and FutureCBase here
class BaseInterfaceClass: public FeatureABase<HAS_FEATURE_A>, public FeatureBBase<HAS_FEATURE_B>, public FeatureCBase<HAS_FEATURE_C>
{/*not flag dependent parts here*/};
//If you want to get rid of the preprocessor flags completely, you could define
//BaseInterfaceClass as a template itself:
template<bool HasA, bool HasB, bool HasC>
class BaseInterfaceClass: public FeatureABase<HasA>, public FeatureBBase<HasB>, public FeatureCBase<HasC>
{/*not flag dependent parts here*/};
Если вы не хотите использовать множественное наследование (поскольку вы не хотите увеличивать объект), вы можете развернуть его в одну цепочку наследования:
template<bool B> class FeatureBBase: public FeatureABase<HAS_FEATURE_A> {};
template<> class FeatureBBase<true>: public FeatureABase<HAS_FEATURE_A> {
public:
virtual void doFeatureB1() = 0;
virtual void doFeatureB2() = 0;
virtual void doFeatureB3() = 0;
};
template<bool B> class FeatureCBase: public FeatureBBase<HAS_FEATURE_B> {};
template<> class FeatureCBase<true>: public FeatureBBase<HAS_FEATURE_B> {
public:
virtual void doFeatureC1() = 0;
}
class BaseInterfaceClass: public FeatureCBase<HAS_FEATURE_C>
{/*not flag dependent parts here*/};
Предполагается, что ваши функциональные флаги в основном являются логическими значениями, поэтому HAS_FEATURE_A
равно 0
, если функция не включена. Если это не так, вы можете сделать параметр шаблона типа int
и специализироваться на 1
вместо true
. Если неиспользуемые флаги функций не определены, вы не сможете полностью избавиться от использования #if
или #ifdef
, поскольку это единственный способ принимать решения, основываясь на том, определен макрос или нет.