Appearance
C++ 引用
引用是变量的别名,提供了另一种访问变量的方式。引用是 C++ 中一个重要的特性,常用于函数参数传递。
1. 引用的基本概念
1.1 声明引用
cpp
类型& 引用名 = 变量名;示例
cpp
#include <iostream>
int main() {
int var = 10;
int& ref = var; // ref 是 var 的引用
std::cout << "var 的值: " << var << std::endl;
std::cout << "ref 的值: " << ref << std::endl;
return 0;
}1.2 引用的特性
- 引用必须在声明时初始化
- 引用不能重新绑定到其他变量
- 引用没有独立的内存空间,只是变量的别名
cpp
#include <iostream>
int main() {
int var1 = 10;
int var2 = 20;
int& ref = var1;
std::cout << "ref 的值: " << ref << std::endl;
ref = var2; // 这是赋值,不是重新绑定
std::cout << "var1 的值: " << var1 << std::endl;
std::cout << "var2 的值: " << var2 << std::endl;
std::cout << "ref 的值: " << ref << std::endl;
return 0;
}2. 引用和函数
2.1 引用作为函数参数
引用作为函数参数可以避免复制大对象,提高效率。
cpp
#include <iostream>
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 10;
int y = 20;
std::cout << "交换前: x = " << x << ", y = " << y << std::endl;
swap(x, y);
std::cout << "交换后: x = " << x << ", y = " << y << std::endl;
return 0;
}2.2 函数返回引用
函数可以返回引用,允许函数调用作为左值。
cpp
#include <iostream>
int& get_element(int arr[], int index) {
return arr[index];
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
get_element(arr, 2) = 100; // 修改数组的第三个元素
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
return 0;
}3. 引用和 const
3.1 const 引用
const引用可以绑定到任何表达式,但不能通过引用修改值。
cpp
#include <iostream>
void print(const int& ref) {
std::cout << "ref 的值: " << ref << std::endl;
// ref = 20; // 错误:不能通过 const 引用修改值
}
int main() {
int var = 10;
print(var);
return 0;
}3.2 const 引用的优势
- 可以绑定到临时对象
- 可以绑定到不同类型的对象(会进行隐式转换)
- 避免复制大对象
cpp
#include <iostream>
void print(const std::string& str) {
std::cout << str << std::endl;
}
int main() {
std::string str = "Hello";
print(str);
print("World"); // 可以绑定到临时对象
return 0;
}4. 引用和指针的区别
| 特性 | 引用 | 指针 |
|---|---|---|
| 声明 | 必须初始化 | 可以不初始化 |
| 重新绑定 | 不能重新绑定 | 可以重新绑定 |
| 空值 | 不存在空引用 | 可以有空指针(nullptr) |
| 内存 | 没有独立的内存空间 | 有独立的内存空间 |
| 运算 | 不支持指针运算 | 支持指针运算 |
4.1 示例
cpp
#include <iostream>
int main() {
int var = 10;
// 引用
int& ref = var;
std::cout << "ref 的值: " << ref << std::endl;
std::cout << "ref 的地址: " << &ref << std::endl;
// 指针
int* ptr = &var;
std::cout << "*ptr 的值: " << *ptr << std::endl;
std::cout << "ptr 的值: " << ptr << std::endl;
std::cout << "ptr 的地址: " << &ptr << std::endl;
return 0;
}5. 引用的应用场景
5.1 避免复制大对象
cpp
#include <iostream>
#include <string>
void print(const std::string& str) {
std::cout << str << std::endl;
}
int main() {
std::string str = "Hello, World!";
print(str);
return 0;
}5.2 修改函数参数
cpp
#include <iostream>
void increment(int& num) {
num++;
}
int main() {
int num = 10;
std::cout << "increment 前: " << num << std::endl;
increment(num);
std::cout << "increment 后: " << num << std::endl;
return 0;
}5.3 链式调用
cpp
#include <iostream>
class Counter {
private:
int count;
public:
Counter() : count(0) {}
Counter& increment() {
count++;
return *this;
}
Counter& decrement() {
count--;
return *this;
}
void print() {
std::cout << "count: " << count << std::endl;
}
};
int main() {
Counter counter;
counter.increment().increment().decrement().print();
return 0;
}6. 右值引用(C++11)
右值引用是 C++11 引入的新特性,用于支持移动语义。
6.1 基本用法
cpp
#include <iostream>
void print(int&& ref) {
std::cout << "右值引用: " << ref << std::endl;
}
int main() {
int x = 10;
print(10); // 右值
// print(x); // 错误:不能绑定到左值
return 0;
}6.2 移动语义
cpp
#include <iostream>
#include <string>
class String {
private:
char* data;
size_t size;
public:
String(const char* str = "") {
size = strlen(str);
data = new char[size + 1];
strcpy(data, str);
}
// 拷贝构造函数
String(const String& other) {
size = other.size;
data = new char[size + 1];
strcpy(data, other.data);
}
// 移动构造函数
String(String&& other) noexcept {
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
}
~String() {
delete[] data;
}
void print() {
if (data) {
std::cout << data << std::endl;
}
}
};
int main() {
String str1("Hello");
String str2 = std::move(str1); // 移动构造
str2.print();
return 0;
}7. 示例:综合运用
现在,让我们看一个综合运用各种引用特性的例子:
cpp
#include <iostream>
#include <string>
// 函数声明
void swap(int& a, int& b);
void print(const std::string& str);
int& get_element(int arr[], int index);
class Counter {
private:
int count;
public:
Counter() : count(0) {}
Counter& increment() {
count++;
return *this;
}
Counter& decrement() {
count--;
return *this;
}
void print() {
std::cout << "count: " << count << std::endl;
}
};
int main() {
// 引用的基本概念
std::cout << "引用的基本概念:" << std::endl;
int var = 10;
int& ref = var;
std::cout << "var 的值: " << var << std::endl;
std::cout << "ref 的值: " << ref << std::endl;
std::cout << std::endl;
// 引用和函数
std::cout << "引用和函数:" << std::endl;
int x = 10;
int y = 20;
std::cout << "交换前: x = " << x << ", y = " << y << std::endl;
swap(x, y);
std::cout << "交换后: x = " << x << ", y = " << y << std::endl;
std::cout << std::endl;
// const 引用
std::cout << "const 引用:" << std::endl;
std::string str = "Hello, World!";
print(str);
print("C++ References");
std::cout << std::endl;
// 函数返回引用
std::cout << "函数返回引用:" << std::endl;
int arr[] = {1, 2, 3, 4, 5};
get_element(arr, 2) = 100;
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
std::cout << std::endl;
// 链式调用
std::cout << "链式调用:" << std::endl;
Counter counter;
counter.increment().increment().decrement().print();
return 0;
}
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
void print(const std::string& str) {
std::cout << str << std::endl;
}
int& get_element(int arr[], int index) {
return arr[index];
}小结
C++ 引用包括:
引用的基本概念:
- 声明引用:
类型& 引用名 = 变量名; - 引用必须在声明时初始化
- 引用不能重新绑定到其他变量
- 声明引用:
引用和函数:
- 引用作为函数参数:避免复制大对象
- 函数返回引用:允许函数调用作为左值
引用和 const:
const引用:不能通过引用修改值- 可以绑定到临时对象
引用和指针的区别:
- 引用没有独立的内存空间
- 引用不能重新绑定
- 不存在空引用
引用的应用场景:
- 避免复制大对象
- 修改函数参数
- 链式调用
右值引用(C++11):
- 支持移动语义
- 提高性能
关键概念:
- 引用:变量的别名
- const 引用:不能通过引用修改值
- 右值引用:支持移动语义
- 链式调用:返回引用以支持连续调用
掌握引用是编写高效 C++ 程序的基础,在后续章节中,我们将学习 C++ 的日期和时间。