类的两大经典类型:带指针 vs 不带指针
在上一篇博客,我们认识到C++通过类将数据和函数封装在一起,解决了C语言全局数据难以管理的问题。但“封装”并非千篇一律,类内部的数据成员类型将深刻影响类的行为、内存布局和资源管理策略。
本篇聚焦于一个最根本的分类维度——类中是否有指针成员,为后续学习拷贝构造、析构函数、运算符重载等核心机制奠定基础。
指针成员的存在性判断
区分“带指针”与“不带指针”的关键在于查看类的私有数据成员声明中是否有 *符号。
判断是否“带指针”是类设计的第一步,它直接决定了后续三大特殊成员函数(拷贝构造、拷贝赋值、析构)是否需要自定义实现。
注意:指针成员 ≠ 动态分配。指针可以指向栈上变量,但实践中带指针的类几乎总是伴随动态内存分配(new),因此资源管理问题随之而来。
易错:看到 char* 就认为必须深拷贝,但若它指向静态常量区则不必,不过这不是一般设计模式。
两种类型的对象在内存中长什么样?
不带指针的对象与带指针的对象在内存布局上有本质区别,这决定了对象拷贝时的行为差异。
不带指针的类:对象拷贝时直接复制所有字节(浅拷贝),两个对象完全独立。
带指针的类:默认拷贝只复制指针值(浅拷贝),导致两个指针指向同一块堆内存,析构时重复释放,引发崩溃。
指针成员带来的资源管理问题
带指针的类必须处理动态内存分配与释放,否则会出现严重的内存错误。
核心问题是 浅拷贝 vs 深拷贝。
❌ 浅拷贝(默认)
1 | String s1("Hello"); |
✅ 深拷贝(自定义)
1 | String(const String& other) { |
带指针的类必须实现“三法则”(Rule of Three):如果类需要自定义析构函数、拷贝构造函数或拷贝赋值运算符中的任何一个,那么通常三个都需要自定义。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 溯境!








