一、引用(&)
1. 引用的概念和定义
• 本质:给已存在的变量取别名,编译器不会为引用变量开辟独立内存空间,与引用对象共用同一块内存。
• 语法格式:类型& 引用别名 = 引用对象;
• 示例:
int a = 0;
int& b = a; // b是a的别名
int& c = a; // 一个变量可多个引用
int& d = b; // 给别名取别名,最终仍指向a
++d; // 操作d等价于操作a
// 输出地址相同,验证共用内存
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
2. 引用的三大特性
1. 必须初始化:声明引用时必须绑定对象,不能单独声明(如int& ra; 编译报错)。
2. 一个变量可多个引用:同一变量可被多个引用别名指向。
3. 引用不可更改指向:一旦绑定某个对象,无法再绑定其他对象(后续赋值是修改对象值,而非改指向)。
• 示例:
int a = 10;
int& b = a;
int c = 20;
b = c; // 不是改指向,是将c的值赋给a(b是a的别名)
3. 引用的使用场景
(1)引用传参(替代指针传参,简化语法)
• 作用:函数内修改实参,避免指针解引用的繁琐,可读性更高。
• 示例(交换函数):
void Swap(int& rx, int& ry) {
int tmp = rx;
rx = ry;
ry = tmp;
}
int main() {
int x = 0, y = 1;
Swap(x, y); // 直接传变量,无需取地址
cout << x << " " << y << endl;
return 0;
}
(2)引用做返回值(减少拷贝,提高效率)
• 作用:返回对象的别名,避免值返回的拷贝开销,可直接修改返回对象。
• 示例(栈顶元素返回):
typedef int STDataType;
typedef struct Stack {
STDataType* a;
int top;
int capacity;
} ST;
// 引用返回栈顶元素,可直接修改
STDataType& STTop(ST& rs) {
return rs.a[rs.top];
}
int main() {
ST st1;
STInit(st1);
STPush(st1, 1);
STTop(st1) += 10; // 直接修改栈顶值
cout << STTop(st1) << endl;
return 0;
}
(3)指针引用(替代二级指针,简化链表操作)
• 作用:给指针变量取别名,无需二级指针即可修改指针本身。
• 示例(链表尾插):
typedef struct ListNode {
int val;
struct ListNode* next;
} LTNode, *PNode;
// 指针引用phead,直接修改头指针
void ListPushBack(PNode& phead, int x) {
PNode newnode = (PNode)malloc(sizeof(LTNode));
newnode->val = x;
newnode->next = NULL;
if (phead == NULL) {
phead = newnode; // 直接修改头指针
} else {
// 遍历尾插逻辑…
}
}
int main() {
PNode plist = NULL;
ListPushBack(plist, 1); // 直接传指针,无需传地址
return 0;
}
4. const 引用(权限控制)
(1)核心规则
• 可引用const对象,必须用const引用(权限不能放大);
• const引用可引用普通对象(权限缩小,合法)。
(2)临时对象与const引用
• 表达式求值、类型转换会产生临时对象(编译器自动创建的未命名对象,具有常量性);
• 临时对象只能用const引用绑定,普通引用会编译报错。
• 示例:
const int a = 10;
// int& ra = a; 报错:权限放大(const→非const)
const int& ra = a; // 合法
int b = 20;
const int& rb = b; // 合法:权限缩小(非const→const)
// rb++; 报错:const引用不可修改
// 临时对象绑定(必须用const引用)
const int& rb = a * 3; // a*3产生临时对象,const引用绑定
double d = 12.34;
const int& rd = d; // 类型转换产生临时对象,const引用绑定
5. 引用与指针的核心区别
| 对比维度 | 引用 | 指针 |
| 内存占用 | 不开辟独立内存,共用对象内存 | 开辟独立内存(存地址) |
| 初始化 | 必须初始化 | 可声明后赋值(语法不强制) |
| 指向修改 | 绑定后不可改指向 | 可随时改指向 |
| 访问方式 | 直接访问对象,无需解引用 | 需解引用(*)访问对象 |
| 空值 | 无空引用,更安全 | 可指向NULL/nullptr,易出空指针 |
| sizeof结果 | 引用类型的大小(如int&→4) | 地址空间大小(32位4/64位8) |
二、inline 关键字(内联函数)
1. 核心概念
• 定义:inline修饰的函数为内联函数,编译时编译器会在调用处直接展开函数体,避免函数调用的栈帧开销,提高执行效率。
• 本质:是编译器建议,而非强制命令——编译器会根据函数复杂度(如代码长度、是否递归)决定是否展开,C++标准无强制展开规则。
2. 适用场景
• 适合:频繁调用、代码简短的函数(如简单的加减、取值函数);
• 不适合:递归函数、代码冗长的函数(编译器会自动忽略inline)。
3. 与C语言宏函数的对比
• 宏函数:预处理阶段文本替换,无类型检查,易出错(如括号缺失导致运算优先级问题);
• inline函数:编译阶段处理,有类型安全检查,语法与普通函数一致,替代宏函数更安全。
• 宏函数易错示例:
// 错误宏(无括号,优先级问题)
#define ADD(a,b) a+b
cout << ADD(1,2)*5 << endl; // 展开为1+2*5=11,不符合预期
// 正确宏(加括号保证优先级)
#define ADD(a,b) ((a)+(b))
cout << ADD(1,2)*5 << endl; // 展开为(1+2)*5=15,符合预期
4. inline函数的使用规范
1. 声明与定义不分离:若将inline函数声明放头文件、定义放源文件,链接时会报“无法解析外部符号”(内联展开后无函数地址,链接器找不到定义)。
◦ 错误示例:
// F.h(声明)
inline void f(int i);
// F.cpp(定义)
void f(int i) { cout << i << endl; }
// main.cpp(调用)
#include "F.h"
f(10); // 链接报错:无法解析外部符号
2. Debug模式默认不展开:VS等编译器的Debug版本为方便调试,默认关闭inline展开,Release版本自动开启。
5. 代码示例
#include <iostream>
using namespace std;
// 内联函数:简单加法,适合展开
inline int Add(int x, int y) {
int ret = x + y;
ret += 1;
return ret;
}
int main() {
int ret = Add(1, 2); // 编译时直接展开为int ret=1+2+1;
cout << ret << endl;
return 0;
}
三、nullptr(C++11空指针关键字)
1. 传统NULL的缺陷
• 本质:NULL是宏,C++中定义为0,C中定义为(void*)0;
• 问题:函数重载时,NULL会被优先匹配int参数版本,而非指针版本,违背空指针使用初衷。
• 示例:
void f(int x) { cout << "f(int x)" << endl; }
void f(int* ptr) { cout << "f(int* ptr)" << endl; }
int main() {
f(NULL); // 匹配f(int x),而非预期的f(int* ptr)
f((int*)NULL); // 强制转换才能匹配指针版本,繁琐
return 0;
}
2. nullptr的优势
• 类型:C++11新增关键字,是特殊指针类型字面值,只能隐式转换为任意指针类型,不能转换为整数类型;
• 作用:完美表示空指针,避免NULL的类型歧义,重载时优先匹配指针参数。
• 示例:
void f(int x) { cout << "f(int x)" << endl; }
void f(int* ptr) { cout << "f(int* ptr)" << endl; }
int main() {
f(nullptr); // 直接匹配f(int* ptr),无需强制转换
return 0;
}
3. 核心规则
• nullptr是指针类型,NULL是整数0(C++);
• 空指针定义优先用nullptr,替代NULL,避免类型歧义。
网硕互联帮助中心


![[从0开始学Java|第十五天]面向对象进阶(抽象类&接口&内部类)-网硕互联帮助中心](https://www.wsisp.com/helps/wp-content/uploads/2026/02/20260206085959-6985ad8f62128-220x150.png)

评论前必须登录!
注册