C++中STL 容器中引用与指针的使用对比(vector<T*> vs vector<T&>)

掌握std::vector<T*> vs std::vector<T&>理解指针与引用在容器中区别和适用场景的关键点

下面将从语法、底层原理、能否使用、典型用途、安全性与扩展等方面进行 详细对比讲解,并辅以示例,帮助吃透这个核心概念。


一、基本对比结论

比较项std::vector<T*>std::vector<T&>
是否合法✅ 合法❌ 非法,引用不能作为容器元素类型
典型用途指向对象的指针集合❌ 不能直接使用
是否可以为空✅ 可存 nullptr❌ 不存在空引用
需要额外注意生命周期吗✅ 是❌ 引用不能存储,强制绑定生命周期
替代方案使用智能指针如 std::unique_ptr<T>std::reference_wrapper<T> 包装引用

二、为什么 std::vector<T&> 不合法?

引用在 C++ 中不是对象,而是变量的别名。STL 容器要求元素可以 复制、移动、存储、管理生命周期,引用显然不满足这些要求。

编译错误示例:

std::vector<int&> vec;  // ❌ 错误:引用不是对象,不能拷贝

三、推荐方案一:使用指针

#include <vector>
#include <iostream>

struct Obj {
    int val;
    Obj(int v) : val(v) {}
    void print() { std::cout << val << "\n"; }
};

int main() {
    Obj a(1), b(2), c(3);
    std::vector<Obj*> vec;

    vec.push_back(&a);
    vec.push_back(&b);
    vec.push_back(&c);

    for (auto* p : vec)
        p->print();  // 输出 1 2 3
}

优势:

  • 可存储任意对象的地址
  • 可以为 nullptr
  • 灵活指向不同对象

注意:

  • 生命周期需自己管理,不能使用已经被释放的对象地址

四、推荐方案二:使用 std::reference_wrapper<T>

虽然不能直接用 vector<T&>,但 C++ 提供了 std::reference_wrapper<T>,它本质上是一个对引用的封装类,可以模拟引用集合。

#include <vector>
#include <functional>  // std::reference_wrapper
#include <iostream>

int main() {
    int a = 1, b = 2, c = 3;
    std::vector<std::reference_wrapper<int>> vec;

    vec.push_back(a);
    vec.push_back(b);
    vec.push_back(c);

    for (auto& ref : vec)
        std::cout << ref.get() << "\n";  // 输出 1 2 3

    vec[0].get() = 10;  // 修改原始变量 a
    std::cout << "a = " << a << "\n";   // 输出 a = 10
}

优势:

  • 实现引用语义存储
  • 可与 std::bind, std::function 协同使用
  • 保持原始变量的引用属性

注意:

  • 仍需保证被引用对象的生命周期大于容器
  • get() 访问封装的引用

五、使用场景总结

需求推荐做法
需要引用对象,但不能复制使用 std::reference_wrapper<T>
需要控制对象生命周期使用 std::unique_ptr<T>
存指针集合并自由操作使用 std::vector<T*>
存值并自动管理使用 std::vector<T> 直接存值

六、进阶对比:vector<T*> vs vector<unique_ptr<T>>

类型是否自动释放语义推荐使用场景
T*❌ 否,需手动 delete指针简单引用外部对象
unique_ptr<T>✅ 自动析构拥有权转移管理生命周期的资源集合
std::vector<std::unique_ptr<MyClass>> vec;
vec.push_back(std::make_unique<MyClass>());

七、结语:选择建议

  • 想要传值修改原始变量 → 用 std::reference_wrapper<T>
  • 想要灵活指向不同对象 → 用裸指针或智能指针集合
  • ❌ 不要尝试 vector<T&> —— C++ 不允许
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云SLAM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值