0

Requirement : Some of the functionality of grand parent class (i.e. Base) need to be changed for layer 2. This changed functionality is same for both Dervied_Layer_2_Case_A and Dervied_Layer_2_Case_B.

Do you see any negative impact of using below type of solution ? I am asking this becoz I haven't seen such pattern before.

struct Base
{
        virtual void doSomething() {  ...  }
};


///// Layer 1 ////////////////////  
template <class BaseType = Base>
struct Dervied_Layer_1_Case_A : public BaseType 
{ 
       static_assert(std::is_base_of<Base, BaseType>::value);

        //This class uses other functionality from Base. Hence the derivation

        void runA() {calls BaseType::doSomething() while working}
};

template <class BaseType = Base>
struct Dervied_Layer_1_Case_B : public BaseType 
{
       static_assert(std::is_base_of<Base, BaseType>::value);

        //This class uses other functionality from Base. Hence the derivation

        void runB() {calls BaseType::doSomething() while working}
};

////////Layer 2 //////////////
struct BaseLayer2 : public Base
{
        //Only below behavior need to be changed. Other functionality of Base used without change
        void doSomething() override {  ...differnet implementation..  }
};


struct Dervied_Layer_2_Case_A : public Dervied_Layer_1_Case_A <BaseLayer2>
{
  //some of the functionality of DerviedCase_1_A is changed
};

struct Dervied_Layer_2_Case_B : public Dervied_Layer_1_Case_B <BaseLayer2>
{
  //some of the functionality of DerviedCase_1_B is changed
}
aKumara
  • 395
  • 1
  • 12
  • It is not immediately obvious to me why `Dervied_Layer_1_Case_[AB]` is a template, unless you want to be able to substitute `Base` with other classes (say, a `Base2` with its own `doSomething()`) as a form of static polymorphism (which you don't show). Access to the base class is of course possible without having it as a template parameter. (The curiously recurring template pattern mentioned earlier in a now-deleted comment *accesses the **derived** class from the base* -- which is generally not possible -- via a template parameter.) – Peter - Reinstate Monica Mar 04 '22 at 07:33
  • `Dervied_Layer_1_Case_[AB]` is a template becoz it's base class need to be changed. may be be I can add a static_assert to ensure `BaseType` is always a derived type of `Base`. I looked at the design patterns mentioned in https://stackoverflow.com/questions/23868740/c-inherit-class-from-template-parameter , but non of them override a grand parent's virtual function. – aKumara Mar 04 '22 at 07:57
  • It's also possible that you are better off without inheritance at all, using injection instead. Each class that is derived in your example would not be in any type hierarchy; instead, it would hold a pointer to a class that implements an interface defining a pure virtual `doSomething()`. That pointer can point to arbitrary classes (and it can do so at runtime, which is more flexible) that implement the interface. – Peter - Reinstate Monica Mar 04 '22 at 08:19
  • in my case inheritance is required as `Base` class's functionality is modified by derived class and base classes need intimate knowledge of parent class's some of the (not all) functionality – aKumara Mar 04 '22 at 08:30
  • @Peter-ReinstateMonica, do you see any thing that can go wrong with my above mentioned approach ? (given static_assert done to ensure `Dervied_Layer_1_Case_A\B`'s BaseType is a derived type of Base) – aKumara Mar 04 '22 at 08:33
  • I added static_assert to my question – aKumara Mar 04 '22 at 08:38
  • IMHO the only drawback is it's hard to maintain. All other errors should be ruled out at compile time. In your simplified example, composition seems better than inheritance. – Louis Go Mar 04 '22 at 08:41
  • `inheritance is required as Base class's functionality is modified by derived class`. This seems like a policy or strategy pattern to me. Inheritance is not required. – Louis Go Mar 04 '22 at 08:44

0 Answers0