看下列代码执行结果,你猜一猜会输出什么?
#include<iostream>
using namespace std;
long long a = 10;
struct A {
virtual void fun(int a=10){
cout << a;
}
};
struct B :public A{
void fun(double) {
cout << 6;
}
};
int main() {
B b;
A a = b;
a.fun(2.6);//输出2
a.fun();//输出10
b.fun(2.6);//输出6
}
问题是如果发生多态的话输出应该全是6啊,这是为什么呢?
首先搞明白默认参数的作用,假设定义fun(int a=10)它的作用就是使用fun()时编译阶段加上参数变成fun(10),这是一种静态行为。
至于有静态形参的虚函数不能进行动态多态,你只需要从生效时间考虑即可,它既然要在编译期间完成变量的赋值行为,那么它会管你运行期会推导出什么类型吗?
简单点来说它在编译期间必须要完成推导,所以它只认类型,是A类型的它就会执行A中的函数它不会管你是否进行了多态,B的对象创建时还是发生了函数覆盖,这是因为函数覆盖发生在编译期间,这时候函数指针已经改变了,所以调用时执行的是B中的函数而不是A中的。
struct A {
virtual void fun(static int b){
cout << a;
}
};
struct B :public A{
void fun(int) {
cout << 6;
}
};
int main(){
B b;
b.fun(0);//输出6
}
那么静态多态呢?
首先回答问题,可以发生函数重载
void fun(int a=10){
cout << 1;
}
void fun(double){
}
int main() {
fun();//没有输出
}
这个问题也很好理解,static不会影响变量的类型,传参的类型不同编译期间推导的结果也会不一样。
总的来说,需要记住当函数是虚函数的时候要避免使用默认参数参数,因为执行带默认参数的函数时函数的选择会发生在编译期间