I was asked to make a slight change on an old project build with Visual Studio 2013 VC++. So, I installed VS2013, made the change, compiled it but its behavior has changed on a code that I didn't touch.
After the update, a virtual method that was calling the method on the derived class is calling the method on the base class now.
I'm not a C++ expert but I can see that this a bad practice. All I want to know if there was a breaking change in C++ around this so I can explain to the person who asked me to update this project.
class BaseItem
{
public:
virtual void SetValue(int first, int* second = nullptr)
{
};
}
class DerivedItem : public BaseItem
{
public:
virtual void SetValue(int first)
{
};
}
BaseItem* item = new DerivedItem();
// Before: SetValue on the DerivedItem was called.
// After: SetValue on the BaseItem is called.
item->SetValue(5, nullptr);
and if I edit the DerivedItem like this:
class DerivedItem : public BaseItem
{
public:
virtual void SetValue(int first, int* second = nullptr)
{
};
}
the SetValue on the DerivedItem is called again.
Function overriding is based on the parameters and their types, not taking default values into account. After the change,
DerivedItem::SetValueis no longer an override ofBaseItem::SetValue, it is just a member function that shadows the base function of same name.You can have the compiler diagnose this for you by using the
overridekeyword whenever you intend overriding to happen:then it will give an error if the function is not actually overriding a function from the base class (as opposed to a silent change in runtime behaviour).
To override a function you will have to make the derived class signature match the base class, as you have found.
In my opinion -- it's cleaner and more robust to avoid default parameters entirely , and add another overload of the function to support a different parameter set. So instead, the base class would have:
and the derived could override either one or both. This approach also plays nicer with existing code that calls SetValue.