Initializing member class with referenced inputs within parent class constructor

47 Views Asked by At

I have a class FRED which takes as input to its constructor the reference to two instances of class BARNEY:

class FRED{
    private:
        BARNEY &barney_inst1;
        BARNEY &barney_inst2;
        
    public:
        FRED(BARNEY &a, BARNEY &b):
            barney_inst1(a), barney_inst2(b) {
        }

And I have a parent class called WILMA which includes an instance of FRED as a member and two instances of class BARNEY:

class WILMA {
    private:
        
        BARNEY foo[2];
        FRED bar;

     WILMA(uint8_t *p) : 
     {
            for(uint8_t i=0;i<2;i++)
            {
                foo[i]=BARNEY(p[i]);
            }
            bar= FRED(foo[0],foo[1]);  //This always fails at compile
     }
}

My problem is that this will never compile, because FRED has no "blank" constructor.

How can I work around this definition of FRED and still include it as a member of WILMA? I can declare the instances of FRED and BARNEY as global and that works, but I don't like having global variables if I can put them inside the parent class. It's messy and harder for future code changes.

I've tried adding a blank constructor and found that this will never work because of the referenced inputs (&a and &b) cannot be left uninitialized and once you initialize them, they cannot be changed. Believe me, I've tried. The compiler always seems to thwart me one way or another.

I've tried declaring bar (the instance of FRED) to be a pointer and using:

 FRED *bar;
  ...
 bar=new FRED(foo[0],foo[1])

This compiles but hangs during execution for some reason I think is related to having a pointer to a class with referenced inputs.

1

There are 1 best solutions below

3
Christian Stieber On

If you have references, then you have to follow the rules for references: you can't change them later.

You could just initialize them in your WILMA constructor:

WILMA(uint8_t *p) : bar(foo[0], foo[1]) { ... }

Or, make it something else, like pointers.

FRED *bar;
  ...
bar=new FRED(foo[0],foo[1])

I would suggest making this a std::unique_ptr<FRED> instead of a raw one. Helps with the cleanup.