C++中vector函数_C++ vector成员函数功能解析

vector::push_back先构造再拷贝/移动,emplace_back直接原地构造;clear()不改变capacity;operator[]越界是未定义行为;vector是特化陷阱,使用代理引用。

vector::push_back 和 vector::emplace_back 的区别在哪

关键不在“能不能加”,而在“怎么加”——push_back 先构造再拷贝/移动,emplace_back 直接在 vector 尾部原地构造。对简单类型(如 int)没差别;但对自定义类,尤其含多参数构造函数或移动开销大的对象,emplace_back 更高效且能绕过隐式转换限制。

  • push_back(MyClass{1, "hello"}):先临时构造 MyClass 对象,再调用移动构造函数插入
  • emplace_back(1, "hello"):直接以 1"hello" 为参数,在 vector 内存中调用 MyClass::MyClass(int, const char*)
  • 如果构造函数是 explicit 的,push_back 可能编译失败,而 emplace_back 仍可用

clear() 后 vector 的容量(capacity)会变吗

不会。clear() 只销毁所有元素、把 size() 置为 0,但底层分配的内存(即 capacity())保持不变。这是为了后续快速复用内存,避免频繁 realloc。

  • 想真正释放内存,得配合 swap 技巧:
    std::vector(v).swap(v);
  • C++11 起可改用 shrink_to_fit(),但它只是请求(非强制),实现可忽略
  • 反复 clear() + push_back(

    )
    多次,capacity() 通常只增不减,除非显式干预

用 operator[] 访问越界时会发生什么

行为未定义(UB)——不抛异常、不报错、不保证崩溃,但程序可能读到垃圾值、触发段错误,或看似正常却藏有隐患。这和 at() 完全不同。

  • v[i]:无边界检查,快但危险;调试时容易漏掉越界问题
  • v.at(i):带检查,越界抛 std::out_of_range 异常,适合开发/测试阶段
  • 迭代器访问(如 v.begin() + i)同样不检查,越界后解引用也是 UB

vector 是不是真正的容器

不是。它是 C++ 标准库中一个特化陷阱:vector 不满足容器要求,内部用位压缩存储,operator[] 返回的是代理对象(std::vector::reference),而非 bool&

  • 不能取地址:&v[0] 编译失败
  • 无法用于需要真实引用的场景,比如绑定到 bool& 参数的函数
  • 迭代器行为异常,*it = true 有效,但 auto& x = *it 会绑定到临时代理,修改无效
  • 真要存布尔值且需标准容器语义,用 vectordeque
实际写代码时,最容易被忽略的是 vector 的代理引用机制和 clear() 不缩容这两点——它们在逻辑正确性上不报错,却会在长期运行或跨平台部署时突然暴露问题。