Skip to content

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++ 引用包括:

  1. 引用的基本概念

    • 声明引用:类型& 引用名 = 变量名;
    • 引用必须在声明时初始化
    • 引用不能重新绑定到其他变量
  2. 引用和函数

    • 引用作为函数参数:避免复制大对象
    • 函数返回引用:允许函数调用作为左值
  3. 引用和 const

    • const引用:不能通过引用修改值
    • 可以绑定到临时对象
  4. 引用和指针的区别

    • 引用没有独立的内存空间
    • 引用不能重新绑定
    • 不存在空引用
  5. 引用的应用场景

    • 避免复制大对象
    • 修改函数参数
    • 链式调用
  6. 右值引用(C++11)

    • 支持移动语义
    • 提高性能

关键概念:

  • 引用:变量的别名
  • const 引用:不能通过引用修改值
  • 右值引用:支持移动语义
  • 链式调用:返回引用以支持连续调用

掌握引用是编写高效 C++ 程序的基础,在后续章节中,我们将学习 C++ 的日期和时间。