2013-08-05 125 views
0

以下main输出的答案是“i = 10的派生类显示”,但我不明白为什么?这个函数肯定是在基类型上调用的?静态基类型和动态派生类型的输出

这里确定答案的思路是什么?

class base 
{ 
    public: 
     virtual void display(int i = 10) 
     { 
      cout<<"Base class display with i = "<<i<<endl; 
     } 

}; 

class derived : public base 
{ 
    public: 
      void display(int i = 20) 
     { 
      cout<<"Derived class display with i = "<< i <<endl; 
     } 

}; 

int main(int argc, char *argv[]) 
{ 
    base *bptr = new derived; 
    bptr->display(); 

     return 0; 
} 

回答

2

看一看Can virtual functions have default parameters?

虚拟函数调用(10.3)使用默认参数在 声明由静态型的 的指针或引用表示所确定的虚拟功能的物体。派生类中的覆盖函数 不会从它覆盖的 函数获取默认参数。

因此,bptr->display();调用的display派生版本,但使用来自base参数,静态类型的指针bptr的。

这是因为参数的默认值必须在编译时确定,而动态绑定则推迟到运行时。在同一个虚拟的基础版本和派生版本中使用不同的默认参数几乎是保证会造成问题。当通过引用或指向基的指针调用虚拟时可能会出现问题,但执行的版本是由派生的版本定义的版本。在这种情况下,为虚拟基本版本定义的默认参数将被传递给派生版本,派生版本使用不同的默认参数进行定义。

+0

好的,所以你可以使用虚函数默认参数的唯一方法是如果你声明静态类型是派生类?派生的d = new Derived(); – user997112

+0

@ user997112您最好使用相同的默认参数来避免任何意外。 – Yang

+0

这种行为的原因是什么,只有这样我才能理解 - 而不是记住这个规则?派生类还有其他类似的规则吗? – user997112