void Test1(int a, int b = 2, char c = '3', string d = "4") { cout << a << endl << b << endl << c << endl << d << endl;

一旦某个参数开始指定默认值,它右边的所有参数都必须指定默认值: 函数声明时,必须按照从右向左的顺序,依次给与默认值

在调用具有默认参数的函数时,若某个有默认参数的参数使用了默认参数, 它右边的所有参数都使用默认参数: 函数调用时,必须按照从左向右的顺序,依次赋值

#include<bits/stdc++.h>
using namespace std;
static void Test0(int a = 0);
static void Test1(int a, int b = 2, char c = '3', string d = "4");
int main() {
    Test0();
    Test1(1);
    //'2'会转换成int,执行Test1
    Test1(1, '2');
    return 0;
void Test0(int a) {
    cout << a << endl;
void Test1(int a, int b, char c, string d) {
    cout << a << endl << b << endl << c << endl << d << endl;

类的一般成员函数

类的虚函数

结论:决不要重新定义继承而来的缺省参数值

#include<bits/stdc++.h>
using namespace std;
class A {
public:
    virtual void Test0(int a = 5) = 0;
class B : public A {
public:
    virtual void Test0(int a = 6) override {
        cout << a << endl;
int main() {
    A* a = new B();
    a->Test0();
    return 0;

虚函数是动态绑定的,即具体被调用的虚函数由那个对象的动态类型决定

缺省参数是静态绑定的,即编译阶段就确定了虚函数的默认参数一定来自Base类;

这样做的原因是:运行效率。如果缺省参数被动态绑定,需要类似查虚表的机制,这将比现在采用的在编译阶段确定缺省值的机制更慢更复杂

比如:上方代码如果调用Test0()

返回地址压栈

调用函数:因为虚函数,需要虚表找到函数指针,跳到函数实际地址执行函数

注意到此时参数已经压栈,虽然可以用类似的机制实现动态绑定,但没必要