struct B{
virtual void f1(string str="base"){
cout<<str<<endl;
}
};
struct D:B{
void f1(string str) override{//此时重写的函数可以没有默认实参
cout<<str<<endl;
}
};
当基类和派生类中的虚函数的默认实参不一致时,动态绑定不会作用在实参上,换句话说,基类指针或基类引用调用虚函数时,默认实参是由静态类型决定的,这里静态类型是基类,所以默认实参为基类中的默认实参。因此,基类和派生类中定义的默认实参最好一致。
例如:
//虚函数有默认实参时,默认的实参由静态类型决定
#include <iostream>
#include<string>
using namespace std;
struct B{
virtual void f1(string str="base"){
cout<<str<<endl;
}
};
struct D:B{
void f1(string str="derived") override{
cout<<str<<endl;
}
};
int main(int argc, char*argv[])
{
B b0;
D d0;
B* b1=&b0;
B* b2=&d0;
b1->f1();
b2->f1();
system("pause");
}
虚函数回避机制:
在派生类重写的函数中,如果要调用基类中相应的虚函数,此时如果没有作用域限定,则将陷入无限递归的状态,因此需要加上基类的作用域限定符,才能防止这种情况。
#include <iostream>
#include<string>
using namespace std;
struct B{
virtual void f1(string str="base"){
cout<<str<<endl;
}
};
struct D:B{
void f1(string str="derived") override{
cout<<str<<endl;
//f1();//自身调用导致无限递归
B::f1();//作用域限定调用基类中虚函数
}
};
int main(int argc, char*argv[])
{
D d0;
B* b2=&d0;
b2->f1();
system("pause");
}
运行结果: