In previous lessons, we saw how we could initialise the members of our classes to different values, using a constructor:
class Character {
public:
Character() {
Health = 100;
}
private:
int Health;
}
This method does have a slight performance cost, as, when our objects are created from our class, the initialisation of the variable is done in two steps rather than one.
First, the variable is declared and memory is assigned for it. Then, later, when we get to the relevant line in our constructor function, a second statement changes the value in that memory location.
Aside from being sub-optimal, this is also unusable for references. As we saw in the previous lesson, references must be initialised with a value, and that value cannot be reassigned.
Given the following classes, how we can we construct a Character
?
class Weapon {};
class Character {
public:
Character() {
Weapon InitialWeapon;
EquippedWeapon = InitialWeapon;
}
Weapon& EquippedWeapon;
};
The way we can solve this is to use a Member Initialiser List - a special syntax that we can attach to our constructor functions, to ensure our member variables are initialised in one step.
The way in which we achieve the above example using a member initialiser list is as follows:
class Character {
public:
Character() : Health{ 150 } {
// Body here
}
private:
int Health;
}
We place the initialiser list between the name and the body of the function, separated by a :
.
We still can provide a function body. It can be blank as in the above example, or we can put any other code in there that we want to run when our objects are first created.
If we do not need to provide a body, we still have to include the braces {
and }
.
How can we refactor the following class to use a member initialiser list?
class Weapon {
public:
Weapon() {
Damage = 100;
}
int Damage;
};
Where we want to initialise multiple variables, we can add those to the list, separated by commas:
class Character {
public:
Character() : Health{ 150 }, Armor{ 0.5f } {
// Body here
}
private:
int Health;
float Armour;
}
Like with the initialisation of any other variables, any expression that results in a value of the correct type can be used.
This is shown in the below example. Remember, C++ is not especially sensitive to white space, so we can generally add line breaks and additional space where needed, if we think it makes our code more readable for humans.
float GetArmour() { return 0.25f; };
class Character {
public:
Character() :
Health{ 100 + 50 },
Armour{ GetArmour() }
{
// Body here
}
private:
int Health;
float Armour;
}
Of course, the above examples are slightly unnecessary. If we wanted all our objects to be initialised with the same value, we wouldn't need an initialiser list (or a constructor) at all - we could just do this:
class Character {
int Health { 150 };
float Armour { 0.5f };
}
However, the strength of initialising variables from constructors is that each object can be initialised with different values, based on parameters passed to the constructor.
Character SmallCharacter { 150, 0.25f };
Character BigCharacter { 300, 0.5f };
With member initialiser lists, we can set our constructors up to support this as follows:
class Character {
public:
Character(int InitialHealth, float InitialArmour) :
Health{ InitialHealth },
Armour{ InitialArmour }
{
// Body here
}
private:
int Health;
float Armour;
}
How can we refactor the following class to use a member initialiser list?
class Weapon {
public:
Weapon(int InitialDamage) {
Damage = InitialDamage;
}
int Damage;
};
This knowledge allows us to address our original problem. We can now store references to other objects from within our class.
We do this by using a member initialiser list to initialise the reference from an argument passed to the constructor:
class Weapon {};
class Character {
public:
Character(Weapon& Weapon) :
EquippedWeapon{ Weapon }
{
// Body here
}
private:
Weapon& EquippedWeapon;
}
We can then create our objects like this:
Weapon SteelSword;
Character Goblin { SteelSword };
Become a software engineer with C++. Starting from the basics, we guide you step by step along the way