std::vector默认存储对象副本,需类支持拷贝或移动;含资源时须实现深拷贝/移动控制;大对象可存unique_ptr或用move;扩容会导致迭代器失效。

vector 里直接存对象,不是指针
默认情况下 std::vector 存的是对象的副本,不是地址。只要你的自定义类满足“可复制”(有拷贝构造函数和赋值操作符)或“可移动”(C++11 起有移动构造/赋值),就能直接 push:
class Person {
public:
std::string name;
int age;
Person(const std::string& n, int a) : name(n), age(a) {}
};
然后这样用:
std::vector<Person> people;
people.push_back(Person("Alice", 30)); // 拷贝构造
people.emplace_back("Bob", 25); // 原地构造,更高效
注意:emplace_back 避免了临时对象+拷贝的开销,推荐优先用它。
类里含指针或资源时必须写析构/拷贝控制
如果类内部持有裸指针、文件句柄、动态分配内存等资源,不手动管理就会出问题——比如两个 Person 对象共享同一块 new 出来的内存,其中一个析构后另一人再访问就崩溃。
典型错误现象:double free or corruption、程序随机崩溃、use-after-free 报错。
必须显式定义(或 = delete):
-
~Person():释放资源 -
Person(const Person&):深拷贝资源 -
Person& operator=(const Person&):深拷贝赋值
或者直接禁用拷贝(改用 std::vector<:unique_ptr>></:unique_ptr>),更安全。
想避免拷贝开销?用 unique_ptr 或 move
如果类很大、拷贝代价高,或者你本来就不希望复制(比如对象状态唯一),两种主流做法:
- 存智能指针:
std::vector<:unique_ptr>></:unique_ptr>,用push_back(std::make_unique<person>("Alice", 30))</person> - 用
std::move转移所有权:Person p("Alice", 30); vec.push_back(std::move(p));—— 此后p处于有效但未定义状态,不能再用
注意:std::move 不是“移动”,只是类型转换;真正移动行为由类的移动构造函数完成。没定义移动构造时,仍会退化为拷贝。
迭代器失效和 vector 扩容的影响
std::vector 在容量不足时会重新分配内存并把旧元素拷贝/移动过去,这会导致所有已有迭代器、引用、指针失效。
如果你保存了某个 Person& ref = people[0];,之后又 push_back 导致扩容,ref 就悬空了。
常见误用场景:
- 循环中边遍历边
push_back - 长期持有
&people[i]或people.data() + i
解决办法:
- 提前
reserve()预留空间 - 改用
std::deque(不保证连续内存,但 push_back 不失效迭代器) - 只存索引或 ID,不存引用
这个坑容易被忽略,尤其在调试时表现不稳定——有时扩容有时不扩容,问题难复现。
立即学习“C++免费学习笔记(深入)”;


















