我被要求对使用 Visual Studio 2013 VC++ 构建的旧项目进行轻微更改。因此,我安装了 VS2013,进行了更改,编译了它,但它的行为在我没有触及的代码上发生了变化。
更新后,调用派生类上的方法的虚拟方法现在正在调用基类上的方法。
我不是 C++ 专家,但我可以看到这是一个不好的做法。我只想知道 C++ 是否对此进行了重大更改,以便我可以向要求我更新此项目的人进行解释。
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);
如果我像这样编辑DerivedItem :
class DerivedItem : public BaseItem
{
public:
virtual void SetValue(int first, int* second = nullptr)
{
};
}
再次调用DerivedItemSetValue
上的。
函数重写基于参数及其类型,不考虑默认值。更改后,
DerivedItem::SetValue
不再是 的重写BaseItem::SetValue
,它只是一个隐藏同名基函数的成员函数。override
每当您打算进行覆盖时,您都可以使用关键字让编译器为您诊断这一点:那么如果该函数实际上并未覆盖基类中的函数(而不是运行时行为的静默更改),它将给出错误。
要重写函数,您必须使派生类签名与基类匹配,正如您所发现的那样。
在我看来,完全避免默认参数并添加另一个函数重载以支持不同的参数集会更干净、更健壮。因此,基类将具有:
并且派生可以覆盖其中之一或两者。此方法还可以更好地与调用 SetValue 的现有代码配合使用。