C++中的指针与引用:区别与2025最佳实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++中的指针与引用:2025年有何区别以及如何选择?

\n\n

想象一下,你站在一扇门前。有两种方式可以进入:你可以拿一把钥匙(指针),或者直接用手开门(引用)。两种方式都能让你进入房间,但运作方式不同。C++中的指针和引用大致也是如此。

\n\n

这个问题是Stack Overflow上最热门的问题之一(浏览量超过200万!)。这并非偶然:混淆pointer和reference是初学者的经典陷阱。到了2025年,随着C++23及新标准的发布,理解这些区别变得更为重要。让我们一劳永逸地弄清楚。

\n\n

指针与引用的关键区别

\n\n

从基础开始。以下是每位C++开发者都需要知道的主要区别:

\n\n
    \n
  • 引用(reference)——是现有变量的别名(alias)。它必须在创建时初始化,并且不能重新指向另一个对象。
  • \n
  • 指针(pointer)——是一个存储另一个变量地址的变量。它可以被重新指向、修改,也可以是nullptr。
  • \n
\n\n

听起来很简单?让我们通过示例来巩固一下。

\n\n

示例1:初始化

\n
#include <iostream>\n\nint main() {\n    int value = 42;\n    \n    // 引用——必须立即初始化\n    int& ref = value;  // OK\n    // int& ref2;       // 编译错误!\n    \n    // 指针——可以不初始化(但这很危险)\n    int* ptr = &value;  // OK\n    int* ptr2 = nullptr; // OK,安全\n    // int* ptr3;        // 未定义行为!\n    \n    std::cout << "ref = " << ref << ", *ptr = " << *ptr << std::endl;\n    return 0;\n}
\n\n

示例2:重新指向

\n
#include <iostream>\n\nint main() {\n    int a = 10;\n    int b = 20;\n    \n    // 引用:一劳永逸地绑定到a\n    int& ref = a;\n    ref = b;  // 并非重新指向引用!只是将a的值赋为b(a = 20)\n    \n    // 指针:可以重新指向\n    int* ptr = &a;\n    ptr = &b;  // 现在ptr指向b\n    \n    std::cout << "a = " << a << ", *ptr = " << *ptr << std::endl;\n    // 输出:a = 20, *ptr = 20\n    return 0;\n}
\n\n

看出区别了吗?引用就像通往同一房间的第二扇门。指针则是一个可以挂到另一扇门上的地址牌。

\n\n

何时使用引用?

\n\n

C++中的引用是函数参数传递的默认选择。为什么?因为它们更安全:你不会意外传递nullptr或忘记解引用。

\n\n

2025年最佳实践:引用

\n\n
    \n
  • 函数参数(按常量引用)——当不需要修改对象时:
  • \n
\n\n
void printMessage(const std::string& msg) {\n    std::cout << msg << std::endl;\n    // msg是一个别名,没有拷贝\n}
\n\n
    \n
  • 从函数返回——当对象在返回后保证存在时:
  • \n
\n\n
class Container {\n    std::vector<int> data;\npublic:\n    // 返回元素的引用(它存在于容器内部)\n    int& operator[](size_t index) {\n        return data[index];\n    }\n};
\n\n
    \n
  • 运算符重载——经典示例:
  • \n
\n\n
Complex& operator+=(const Complex& other);  // 按引用返回*this
\n\n

何时使用指针?

\n\n

指针是C++的瑞士军刀。它们更强大,但需要谨慎使用。到了2025年,由于智能指针的出现,指针的使用变得更加规范。

博客

书籍推荐