std::string和vector成员会自动初始化与析构,需在初始化列表中显式构造以避免额外开销,预估容量时用reserve,拷贝为深拷贝、移动为转移指针,禁用拷贝需显式删除。

string 成员的初始化和赋值要注意什么
类里声明 std::string 成员时,它会自动调用默认构造函数初始化为空字符串,不需要手动写 "" 或 std::string()。但如果你在构造函数初始化列表里显式初始化,优先用移动语义或直接传参,避免隐式转换带来的临时对象开销。
- 推荐:在初始化列表中用
name(std::move(s))接收右值,或name(s)复制(s是const std::string&) - 避免:在构造函数体内写
name = s;—— 这会触发一次默认构造 + 一次赋值,多一次内存分配 - 注意:如果成员是
const std::string,必须在初始化列表中赋值,不能在构造函数体里“赋值”
vector 成员的容量和元素添加别踩 realloc 坑
std::vector 成员默认构造后大小为 0、容量可能为 0 或实现相关的小值。频繁 push_back 可能多次触发内存重分配,尤其在类构造初期就批量插入时。
- 若已知大致数量(比如读配置预估最多 100 个 item),在初始化列表里用
items(100)预留空间,或构造后立刻调用items.reserve(100) - 不要在循环里反复调用
vector.size()做条件判断再push_back——除非你真需要动态控制,否则先resize再按索引赋值更快 - 成员是
std::vector<:string></:string>时,拷贝整个 vector 会深拷贝所有 string,开销明显;考虑用std::vector<:string_view></:string_view>(C++17+)或指针/引用语义替代,如果只是只读访问
类析构时 string 和 vector 会自动清理吗
会。只要没用 new 手动分配内存,std::string 和 std::vector 的析构函数会自动释放内部堆内存。你不需要、也不应该在析构函数里写 data.clear() 或 delete[]。
- 例外:如果你用
std::vector<char></char>存二进制数据,并通过&vec[0]拿裸指针传给 C API,且该 API 会保存这个指针——那就要确保 vector 生命周期长于 C API 使用期,否则析构后指针悬空 - 如果成员是
std::vector<:unique_ptr>></:unique_ptr>,析构时会自动调用每个unique_ptr的析构,进而释放T对象,无需额外操作 - 注意:继承体系中,若基类有虚析构函数,派生类的 string/vector 成员仍会正常析构;但若基类析构非虚,而你用基类指针 delete 派生类对象,成员析构行为未定义
拷贝和移动语义下 string/vector 成员怎么表现
默认生成的拷贝构造/赋值会逐个拷贝每个 std::string 和 std::vector 成员(深拷贝),移动操作则会转移内部指针,不分配新内存。
- 如果你的类有指针成员或外部资源,只依赖默认移动可能出错——要显式定义移动构造函数,并把 string/vector 成员用
std::move传给基类或成员初始化列表 - 移动后原对象的 string/vector 仍处于有效但未指定状态(通常是空),不能假设其内容,但可以安全赋值或销毁
- 想禁用拷贝?删掉
= delete拷贝函数即可,string/vector 本身不阻止你这么做;但要注意,禁用拷贝后,容器如std::vector<myclass></myclass>就无法使用 push_back(除非提供移动)
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











