C++ 入门不迷路:缺省参数、函数重载与引用轻松拿捏
C++ 作为一门强大而灵活的语言,入门时最容易让人“迷路”的就是这三个特性:缺省参数(Default Arguments)、函数重载(Function Overloading)和引用(References)。它们看似简单,却常常混淆新手。别担心,今天用最接地气的例子帮你彻底拿捏!
1. 缺省参数(Default Arguments)
定义:给函数的参数设置默认值,当调用时不传该参数,就自动使用默认值。
核心规则:
- 缺省参数必须从右往左连续设置(一旦某个参数有默认值,它右边的也必须有)。
- 只能在函数声明中设置缺省值(定义时一般不重复写)。
示例:
#include <iostream>
using namespace std;
// 函数声明:从右边开始设置默认值
void greet(string name, string prefix = "Mr.", string suffix = "!") {
cout << "Hello, " << prefix << " " << name << suffix << endl;
}
int main() {
greet("Alice"); // 输出:Hello, Mr. Alice!
greet("Bob", "Dr."); // 输出:Hello, Dr. Bob!
greet("Eve", "Ms.", "~~~"); // 输出:Hello, Ms. Eve~~~
return 0;
}
常见误区:
// 错误!缺省参数不能跳跃
void bad(string name = "Guest", string prefix); // 编译错误
// 正确写法
void good(string name, string prefix = "Mr.");
实战建议:常用于简化接口(如日志函数、配置函数),但不要滥用——过多默认值会让调用者看不清意图。
2. 函数重载(Function Overloading)
定义:同一个函数名,根据参数个数、类型或顺序的不同,提供多个实现版本。编译器根据调用时的实参自动选择最匹配的版本。
核心规则:
- 函数名相同
- 参数列表不同(个数、类型、顺序,至少有一个不同)
- 返回类型不参与重载决策(不能仅靠返回类型区分)
示例:
#include <iostream>
using namespace std;
void print(int x) {
cout << "整数: " << x << endl;
}
void print(double x) {
cout << "浮点数: " << x << endl;
}
void print(string s) {
cout << "字符串: " << s << endl;
}
void print(int a, int b) {
cout << "两个整数: " << a << ", " << b << endl;
}
int main() {
print(42); // 调用 int 版本
print(3.14); // 调用 double 版本
print("Hello"); // 调用 string 版本
print(1, 2); // 调用双参数版本
return 0;
}
常见误区:
// 错误!仅返回类型不同不算重载
int add(int a, int b);
double add(int a, int b); // 编译错误
// 正确:参数类型不同
int add(int a, int b);
double add(double a, double b);
实战建议:非常适合实现“同一操作、不同数据类型”的场景,如 max()、abs() 等通用函数。
3. 引用(References)
定义:给变量起一个“别名”,本质上是变量的另一种名字。引用必须在定义时初始化,且一旦绑定不可更改。
核心特点:
- 引用不是对象,而是对象的别名
- 没有“空引用”(不像指针可以是 nullptr)
- 常用于函数参数(避免拷贝大对象)和返回值(延长生命周期)
示例:
#include <iostream>
using namespace std;
void increment(int& x) { // 引用传参,能真正修改原变量
x++;
}
int& getRef(int& a) { // 返回引用
return a;
}
int main() {
int a = 10;
int& ref = a; // ref 是 a 的别名
ref = 20; // 实际修改了 a
cout << a << endl; // 输出 20
increment(a); // 传入引用,函数内修改生效
cout << a << endl; // 输出 21
getRef(a) = 100; // 通过返回的引用直接修改 a
cout << a << endl; // 输出 100
return 0;
}
引用 vs 指针 对比(入门必知):
| 特性 | 引用 (&) | 指针 (*) |
|---|---|---|
| 必须初始化 | 是 | 否(可为 nullptr) |
| 可否重新绑定 | 否(一生只爱一个) | 是(可指向其他地址) |
| 语法 | 干净(像普通变量) | 需要 * 和 -> |
| 是否可为空 | 不可 | 可 |
常见用法:
- 函数参数:
void swap(int& a, int& b)—— 高效且能修改原值 - const 引用:
void print(const string& s)—— 避免拷贝,又不修改 - 返回引用:返回容器元素或静态变量,避免不必要拷贝
三者结合实战案例
#include <iostream>
using namespace std;
// 综合运用:重载 + 缺省参数 + 引用
void log(const string& msg, const string& level = "INFO") {
cout << "[" << level << "] " << msg << endl;
}
void log(int value, const string& level = "DEBUG") {
cout << "[" << level << "] Value: " << value << endl;
}
int main() {
log("程序启动"); // 使用默认 INFO
log("连接失败", "ERROR"); // 指定级别
log(404); // 重载调用,整数版本
return 0;
}
总结速记表
| 特性 | 关键词 | 关键点 | 典型场景 |
|---|---|---|---|
| 缺省参数 | = 默认值 | 从右往左、声明处设置 | 简化函数调用 |
| 函数重载 | 同名不同参 | 参数列表决定,不看返回类型 | 通用操作支持多种类型 |
| 引用 | int& ref | 别名、必须初始化、不可重新绑定 | 高效传参、避免拷贝、修改原值 |
掌握了这三个特性,你在 C++ 入门路上就再也不会迷路了!它们是后续学习模板、STL、智能指针等高级特性的基石。
想看更多实战(如引用在 STL 中的应用、重载与模板的区别),随时告诉我,继续陪你进阶!🚀