C++多态中虚函数的默认参数问题
1.基类中虚函数的默认参数会在编译过程就被保存,再调用子类的函数后发生多态,编译器会使用基类的默认参数,这是因为是实参值由静态类型决定,而此时的静态类型是父类的指针或引用。
#include <iostream>
class Base {
public:
virtual void func(int i = 10) {
std::cout << "Base" << std::endl;
}
};
class Derived : public Base {
public:
void func(int i = 0) {
std::cout << "Derived: " << i << std::endl;
}
// 或者不加默认参数,此函数依然覆盖的是 Base 中的 func 函数
// void func(int i) {
// std::cout << "Derived: " << i << std::endl;
// }
};
int main() {
Base *p = new Derived;
p->func();
p->func(1);
return 0;
}
运行结果:
2.基类有默认参数而子类没有,则重写的 func 函数是 Derived 中的新成员。因为参数数量不一样,Derived 中的重写 func 函数不是从 Base 中继承而来,但是 Derived 依旧继承了 Base 中的 func 函数,所以用 Base 指针调用 func 发生多态,而用 Derived 指针调用的 func 函数才是自己定义的新成员。
#include <iostream>
class Base {
public:
virtual void func(int i = 10) {
std::cout << "Base" << std::endl;
}
};
class Derived : public Base {
public:
void func() {
std::cout << "Derived" << std::endl;
}
};
int main() {
Base *p = new Derived;
p->func();
Derived *q = new Derived;
q->func();
return 0;
}
运行结果:
3.子类中有默认参数而基类没有,结果和 2 中一样,原因也一样,但要注意如果用父类指针调用 func 函数并传入了参数,编译器会报错,因为父类中的 func 的函数没有参数,又因为父类指针不能调用子类的非继承而来的函数,因此没有函数与之匹配。
#include <iostream>
class Base {
public:
virtual void func() {
std::cout << "Base" << std::endl;
}
};
class Derived : public Base {
public:
void func(int i = 10) {
std::cout << "Derived" << std::endl;
}
};
int main() {
Base *p = new Derived;
p->func();
// 如果传入参数会报错,因为父类中的 func 的函数没有参数,
// 又因为父类指针不能调用子类的非继承而来的函数,
// 因此没有函数与之匹配,所以编译器会报错
// p->func(3);
Derived *q = new Derived;
q->func();
return 0;
}