• C++
  • C++ 函数重载|零基础通俗易懂完整教程

  • @ 2026-7-31 20:57:51

C++ 函数重载|零基础通俗易懂完整教程

目标:看懂概念、分清规则、避开坑,全部代码带详细注释,直接复制运行。

前置基础:会写普通函数、调用函数。不懂也没关系,跟着注释理解。

一、什么是函数重载(人话解释)

同一个函数名字,不同参数列表,编译器自动匹配调用哪个版本。 举生活例子:

  • 喝水(用杯子)
  • 喝水(用瓶子) 函数名都叫喝水,但是传入的东西不一样,就是重载。

C++规则:同一个作用域内,函数名相同,参数列表不同 → 构成重载。

⚠️重点区分: 参数列表 = 参数个数、类型、顺序 返回值不能作为重载区分依据!

二、最简入门示例

#include <iostream>
using namespace std;

// 版本1:接收1个int整数
void show(int a)
{
    cout << "整数版本:" << a << endl;
}

// 版本2:接收1个double小数
void show(double a)
{
    cout << "小数版本:" << a << endl;
}

int main()
{
    show(100);      // 传入整数,自动调用 int版本
    show(3.14);     // 传入小数,自动调用 double版本

    return 0;
}

运行结果:

整数版本:100
小数版本:3.14

✅两个函数名字都叫show,参数类型不同 → 函数重载

三、构成重载的3种合法情况

情况1:参数个数不同

#include <iostream>
using namespace std;

// 1个参数
int add(int a)
{
    return a;
}

// 2个参数
int add(int a, int b)
{
    return a + b;
}

// 3个参数
int add(int a, int b, int c)
{
    return a + b + c;
}

int main()
{
    cout << add(10) << endl;
    cout << add(10, 20) << endl;
    cout << add(10, 20, 30) << endl;
    return 0;
}

情况2:参数类型不同(最常用)

#include <iostream>
#include <string>
using namespace std;

void print(int x)
{
    cout << "整型:" << x << endl;
}

void print(string s)
{
    cout << "字符串:" << s << endl;
}

int main()
{
    print(666);
    print("你好C++");
    return 0;
}

情况3:参数顺序不同(类型顺序)

#include <iostream>
using namespace std;

void func(int a, double b)
{
    cout << "int在前,double在后" << endl;
}

void func(double a, int b)
{
    cout << "double在前,int在后" << endl;
}

int main()
{
    func(10, 3.14);
    func(3.14, 10);
    return 0;
}

四、重中之重:不能构成重载的误区(新手高频踩坑)

❌误区1:只有返回值不一样,不算重载!代码直接报错

// 错误示范!无法重载
int test(int a)
{
    return a;
}

double test(int a)
{
    return a;
}

原因:编译器调用函数时,不会先看接收什么变量,无法区分调用哪个。

❌误区2:仅仅参数名字不同,不算重载

void fun(int x)
{}
void fun(int y)
{}
// 参数列表完全一样,只是变量名不同 → 重复定义,报错

❌误区3:作用域不同,不算重载

函数写在不同类、不同命名空间,不属于重载。

五、难点:默认参数 和 重载冲突(大坑!)

#include <iostream>
using namespace std;

void test(int a)
{
    cout << "版本1" << endl;
}

// 带有默认参数
void test(int a, int b = 100)
{
    cout << "版本2" << endl;
}

int main()
{
    test(10);
    // 编译器懵逼:
    // 可以调用test(int)
    // 也可以调用test(int, int=100)
    // 产生二义性 → 编译报错!
    return 0;
}

经验建议:重载函数尽量不要混用默认参数,极易产生歧义。

六、函数重载底层原理(通俗讲解,可选阅读)

C语言不支持重载! C++编译器内部会修改函数名(名字修饰 name mangling) 示例:

show(int) → 内部被改成 _Z4showi
show(double) → 内部被改成 _Z4showd

表面名字相同,底层名字不同,所以不会冲突。

注意:C语言函数不会改名,所以C语言没有重载。

七、引用 & 普通参数重载拓展(进阶了解)

#include <iostream>
using namespace std;

void func(int x)
{
    cout << "普通值传递" << endl;
}

void func(int &x)
{
    cout << "左值引用" << endl;
}

int main()
{
    int a = 10;
    func(a);   // 优先匹配 int&
    // func(20); // 常量无法绑定普通左值引用,会匹配func(int)
    return 0;
}

八、完整综合练习案例(可直接复制运行)

需求:重载calc函数,分别实现两个整数相加、两个小数相加、三个整数相加

#include <iostream>
using namespace std;

// 两个整数相加
int calc(int a, int b)
{
    return a + b;
}

// 两个小数相加
double calc(double a, double b)
{
    return a + b;
}

// 三个整数相加
int calc(int a, int b, int c)
{
    return a + b + c;
}

int main()
{
    cout << calc(1, 2) << endl;
    cout << calc(2.5, 3.5) << endl;
    cout << calc(1, 2, 3) << endl;
    return 0;
}

九、新手速记总结清单

✅构成重载条件(同时满足)

  1. 在同一个作用域
  2. 函数名字完全相同
  3. 参数列表(个数 / 类型 / 顺序)至少一处不同

不能作为重载依据

  1. 仅仅返回值不同
  2. 仅仅参数变量名字不同

⚠️避坑提醒

  1. 重载 + 默认参数 容易产生调用歧义,谨慎使用
  2. 调用时注意类型自动转换,可能匹配到意料之外的重载版本

0 条评论

目前还没有评论...