UGameUserSettings. Calling virtual function from constructor

Hi!

I found bad place in the constructor of UGameUserSettings. There is a calling virtual function SetToDefaults. So if we override this function in the child class, this function never be called in the constructor.

I think you need to split this function on two: SetToDefaults (as virtual) and SetToDefaults_Internal (as private nonvirtual). And call SetToDefaults_Internal in constructors and SetToDefaults.

Hope you fix this in next releases :slight_smile:

Hey Mdeni-

When you override the class, you can call the parent’s constructor with a Super call, which would run SetToDefaults the same way UGameUserSettings does in its constructor. An example of this can be seen in the UGameUserSettings constructor where it calls its parent constructor (which is UObject). Additionally, if you are overriding the SetToDefaults function itself, you can call Super::ResetToDefaults(); inside your overridden function to call the parent implementation whenever your version of SetToDefaults is called.

Cheers

Doug Wilson

Hi, i try to explain on the simple example:

#include <stdio.h>

class A
{
public:

	A() 
	{ 
		SetToDefaults(); 
	}
	
	virtual void SetToDefaults()
	{
		printf("A::SetToDefaults \n");
	}
};

class B : public A
{
public:

	B() : A() {  }

	virtual void SetToDefaults() override
	{
		A::SetToDefaults();
		printf("B::SetToDefaults \n");
	}
};

void main(int argc, char* argv[])
{
	B b;
}

We expect to see:

A::SetToDefaults
B::SetToDefaults

But we really will see only:

A::SetToDefaults

The same error may bee in the UGameUserSettings.

In this example, SetToDefaults is overriden in the child class (B) such that when B::SetToDefaults is called, it first calls A::SetToDefault followed by the additional printf in your overriden function (line 27 above). However, you are not actually calling your B::SetToDefaults function. When an object of type B is created, you are calling the parent implementation rather than your child implementation (A::SetToDefaults). For the results you are looking for, you would need to use

B() 
{ 
     SetToDefaults(); 
}

This will call B::SetToDefaults when you create object B, which will in turn call A::SetToDefaults.