纯虚函数中的默认值参数

时间:2018-11-13 01:35:12

标签: c++ inheritance polymorphism

我提交了一些代码:

抽象类:

virtual void someFunction(std::vector<someObject*> & iObject) = 0;
virtual void someFunction(std::vector<someObject*> & iObject, bool aSwitch) = 0;

第一个函数已经存在,我添加了第二个函数以避免在纯方法中具有默认值参数。

派生类中的标题:

virtual void someFunction(std::vector<someObject*> & iObject);
virtual void someFunction(std::vector<someObject*> & iObject, bool aSwitch = false);

预期用途:

someFunction(std::vector<someObject*> & Object);

someFunction(std::vector<someObject*> & Object, true);

someFunction原来是-已经存在,我添加了开关。 效果很好,但我很困惑。

我有一个代码审查员说,我应该在纯虚函数中包括一个默认值,以避免两个函数签名。我记得曾经读过,纯虚函数中的默认值不是一个好主意,但是我不能争论一个正确的观点,并且文章似乎也不清楚为什么。

如果我添加了默认值,是否会导致歧义,如果这样,我在派生的虚方法中仍然需要默认值吗?

我可以只在纯虚函数中添加默认值,而不能在派生类头中删除第一个函数吗?最佳做法是什么?

1 个答案:

答案 0 :(得分:2)

常规默认参数

函数的默认参数不绑定到函数本身,而是绑定到调用上下文:将使用在调用范围内为该函数声明的默认值(请参阅C ++标准,[dcl.fct.default])。对于example

void f(int a=1);     // forward declaration with a default value for the compilation unit
void f(int a)        // definition 
{
    cout<<a<<endl; 
}
void g() {
    void f(int a=2);  // declaration in the scope of g
    f();
}
int main() {
    f();            // uses general default => 1
    g();            // uses default defined in g => 2
    return 0;
}

虚函数的默认参数

此逻辑适用于所有功能,因此也适用于纯虚函数。唯一的事情是,所考虑的函数声明(及其默认值)是编译器已知的对象类之一。因此,取决于用于调用它的对象类型,同一对象的同一函数可能具有不同的默认参数。对于example

struct A {
    virtual void f(int a=1) = 0;    
};
struct B:A {
    void f(int a) override ;     
};
struct C:A {
    void f(int a=2) override ;     
};

void B::f(int a)        // definition 
{
    cout<<"B"<<a<<endl; 
}
void C::f(int a)        // definition 
{
    cout<<"C"<<a<<endl; 
}

int main() {
    B b; 
    C c; 
    A *x=&c, *y=&b;    // points to the same objects but using a polymorphic pointer
    x->f();  // default value defined for A::f() but with the implementation of C ==> C1   
    y->f();  // default value defined for A::f() but with the implementation of B ==> B1
//  b.f();  // default not defined for B::f() so cannot compile   
    c.f();  // default value defined for C::f(); ==> C2
}

很高兴

  • 默认参数不会更改函数的签名。它仍然是相同的功能。
  • 不同的默认参数不会影响ODR规则。因此,您可以在不同的编译单元中使用不同的默认值,并且它仍然是相同的功能。
  • 默认参数由调用者提供,而不是由函数本身提供
  • 如果为基类和派生类定义了不同的默认参数,则需要格外小心,因为根据调用函数的方式,可能会使用不同的默认值。