Search code examples
c++windowsvisual-studio-2013initialization-list

Is it possible to initialise a reference type through an initialisation list?


Firstly, my apologies if this is a poor question. I am new to C++.

I have a set of class headers that contain a reference type field, which is an interface (class built up from pure virtual functions). I would like to initialise my class so that by default the reference type field is set to a certain "concrete" derived class, and this is done using the default constructor (parameterless!). I would also like to be able to override this initialisation with another "concrete" derived class.

So far, I have class headers as follows:

class Foo {

public:

Foo();

Foo(IBar & bar);

protected:

/* Update 1: const field */
const IBar & bar;

...
}

But I am struggling with the implementation:

/* Is it possible to create the reference type through the initialisation list? */

/* Update 2: corrected initialisation of bar field from "BarDerivedA() bar" to "BarDerivedA()" */
Foo::Foo()
: bar(BarDerivedA())
{

}

/* Override */
Foo::Foo(IBar & bar)
: bar(bar)
{

}

Update We found that using this potential design wasn't going to be efficient. The default for const IBar & bar will almost always be the same object for every class with the field, with the exception of unit testing - we want to be able to swap in mock classes as required.

I don't want to constantly create the same object on the stack so will work on a factory for these group of objects.

I have gone down the route of a single constructor as follows:

Foo::Foo(IBar & bar)
: bar(bar)
{

}

If someone wants to provide an appropriate answer regarding the setting of class reference fields to a temporary object in the initialisation list (i.e. can only do it for const fields, and will go out of scope outside of the constructor) I will mark it as the accepted answer. Or alternatively mark it as an appropriate duplicate.


Solution

  • You may add the default object in the class, something like:

    class Foo {
    public:
        Foo() : bar(defaultBar);{}
        Foo(IBar& bar) : bar(bar) {}
    
    protected:
        const BarDerivedA defaultBar; // Before the reference.
        const IBar& bar;
    };