C++ constructor question from tutorial

Hi everyone,

I’m working through the tutorial Build a MIDI synthesizer and I am also pretty new to C++. At the moment I am trying to understand how the MainContentComponent is initialised.

As the tutorial states:

Our MainContentComponent class contains the following data members.

SynthAudioSource synthAudioSource;
MidiKeyboardState keyboardState;
MidiKeyboardComponent keyboardComponent;

The synthAudioSource and keyboardComponent members are initialised in the MainContentComponent constructor.

MainContentComponent()
    : synthAudioSource (keyboardState),
      keyboardComponent (keyboardState, MidiKeyboardComponent::horizontalKeyboard)
{
 ...
}

Now from what I can see here, the keyboardState variable is implicitly initialised by the default MidiKeyboardState constructor.

I have read that

non-static data members are initialized in the order they were declared in the class definition

So how can the synthAudioSource be initialised with the keyboardState ? Shouldn’t keyboardState be not-yet initialised since it is declared AFTER the synthAudioSource member?

I messed around with changing the order of the 3 declarations and it seems to compile fine in Xcode whatever order they are declared in. Is this just some compiler setting that will magically reorder the declarations or what?

The other thing that’s slightly confusing is that we are passing keyboardState to the initialiser of a SynthAudioSource instead of a SynthAudioSource object. I suppose that’s a C++ thing? I get that keyState is the required constructor argument for SynthAudioSource, so I assume that it’s a shorthand where providing an argument matching the type expected by the constructor will be passed through to the constructor - kind of like this: (?)

MainContentComponent()
    : synthAudioSource (new SynthAudioSource(keyboardState)),
      keyboardComponent (new MidiKeyboardComponent(keyboardState, MidiKeyboardComponent::horizontalKeyboard))
{
 ...
}

Thanks in advance!

Please check out some tutorials on constructor member initializer lists and how references are used and work in C++.
If you know how to use your debugger, declare and instance of the class somewhere, add a breakpoint where you declared it, run it, and ‘step in’ to see the construction order of all of the class members.

Edit: removed wrong information

That is incorrect. From cppreference:

  1. Then, non-static data member are initialized in order of declaration in the class definition.

I think that means we have a bug in our tutorials, thanks for raising this @cts.

My fault, you’re right

Even if it is a bug, it’s interesting that the code still works. I tried to recreate a similar situation in a much simpler C++ program and it definitely did not work properly with the members declared in the wrong order.

The compiler warning flag -Wreorder will complain if the order of the members in the initializer list doesn’t match their order of declaration.

In Projucer, you can add that flag to the “Extra Compiler Flags” field, or enable “Add Recommended Compiler Warning Flags”, which adds -Wreorder and a bunch of other very useful warnings.

4 Likes