1
votes

I have a requirement where I want to initialize a Base class member in derived class.

class SuperBase
{
public:
    virtual void Set();
};

class Base:public SuperBase
{
protected:
    int *pVal;
public:
    void Set()
    {
       //Some Logic
    }
};

class Derived1: public Base
{
public:
   // I want to Initialize Base::pVal here and after 
   // that I want to have this value in Set() of Base.
};

class Derived2: public Base
{
  //...Same functionality as Derived1; 
  //...
};

int main()
{
  SuperBase *s = new Derived1; 
  // Here when I create a Derived1 object automatically, 
  // the value for pVal will be initialized 
  s->Set();

 //After calling this Set, I want to get the pVal value access in Set.
}

I know that it is an easy thing to do. But these are the things which I cannot use for this problem:

  • I cannot use Constructor Initializer List for passing values from derived class to Base [I know that I can easily do this through Constructor Initialiser List but there is a requirement where I don't want the existing Class Constructor]

  • I have tried using CRTP[curiously recurring template pattern], but that is also not suitable as it uses a type of static binding, and in higher view, I have to decide at run time which class object to call Derived1,Derived2.

  • I also don't want to write any get() in Derived1,Derived2 as I want to only assign values there. This is also a part of my requirement.

  • I want the Set logic to be only present in Base class and if there is any special case of Set, then I will override Set in Derived classes, otherwise I will access it from Base.

Any Suggestions??? Any Design Patterns??

4
What do you want to initialize it with? nullptr? - lapk
No I want to add initialize it with proper values...That values will be diferenr for Derived1 & Derived2 - Saby
I must be missing something... Whats stopping you from just assigning to pVal in your derived constructors (or anyplace else for that matter)? It's protected, not private; you have access to it. Or is the magic puzzle piece you neglected to mention that Base needs it in its constructor ? - WhozCraig
@WhozCraig: I want to implement this logic in existing code and my Constructor is loaded with lot of initilizer list values, and in this example I have given only one "int*a" actually I have to assign a lot of values. So I want to avoid the Constructor use... - Saby
@Saby So you want to avoid using constructor which is designed for that sort of things and create your own function? - lapk

4 Answers

3
votes

IMHO, You could do this way:

Option 1 : a) Override the Set() in Derived1;

b) In Derived1::Set,
-- assign the pVal desired value.

-- Call Base::Set

Sample code:

void Derived::Set(){
    pVal = /*some value*/;

    Base::Set(); 

}

Option 2: As pointed by Angew

class Derived1: public Base
{
 public:
  Derived()
  {
    pVal = /*some value*/;
  }
};

The SuperBase *s = new Derived1; will invoke the above constructor and pVal would be set.

1
votes

You can only initialise a data member of a class in a member-initialiser-list of that class's constructor. There's no other way. So if you need initialisation, you'll have to add an appropriate constructor to Base and use it (it can be protected, of course).

On the other hand, if it would be enough for your purposes to assign a value into pVal (after it's been initialised by Base's constructor), you can simply do that in the body of the constructor of Derived1 and Derived2:

class Derived1: public Base
{
public:
  Derived()
  {
    pVal = whatever;
  }
};
1
votes

Create constructors for this purpose.

class Base: public SuperBase {
public:
    Base() : pVal(0) {} // Default constructor
protected:
    int *pVal;
    Base(int* Val = 0 /* default value */) : pVal(Val) {} // special constructor
    ...
};

class Derived1: public Base {
public:
   Derived1() : Base(p1 /* Set whatever you want here */) {
   }
};

class Derived2: public Base {
public:
   Derived2() : Base(p2 /* Set other value here */) {
   }
};
0
votes

You could add another level of inheritance, between the Derived1/Derived2 classes and the Base class, who has a constructor initializing pVal.