智能指针是什么?能否为?
摘要:基本概念 问题背景 在 C++ 中,手动管理资源(内存、文件描述符、互斥锁、数据库连接等)时,容易因异常、提前返回等意外情况导致资源泄漏。例如: class A { int size; char *p;
基本概念
问题背景
在 C++ 中,手动管理资源(内存、文件描述符、互斥锁、数据库连接等)时,容易因异常、提前返回等意外情况导致资源泄漏。例如:
class A {
int size;
char *p;
public:
A(int s=1):size(s){p = new char[s];}
~A(){delete [] p;} // 析构函数释放堆内存
};
void someFunction() {
A *p = new A(100); // 分配资源
// 若此处提前返回或抛出异常,delete p 无法执行,导致内存泄漏
...
delete p; // 手动释放资源,可靠性低
}
这种直接指向资源、无自动管理能力的指针称为原始指针(raw pointer),其核心缺陷是:无法保证资源在任意场景下被妥善释放。
智能指针核心定义
智能指针是 C++ 提供的类模板,用于自动化管理资源,核心特征:
本质是栈对象(局部变量),而非真正的指针;
内部封装了指向资源的原始指针;
离开作用域时,自动调用析构函数释放资源(无需手动操作);
重载 operator-> 和 operator* 运算符,用法与普通指针一致。
智能指针对象(栈上)
├─ 成员:原始指针 *p(指向堆/资源)
├─ 重载:operator->、operator*
└─ 析构函数:自动释放 *p 指向的资源
↓
资源(堆内存/文件描述符/互斥锁等)
智能指针分类详解
auto_ptr(C++17 已废弃)
基本用法
std::auto_ptr 是早期智能指针,核心作用是自动释放资源,需包含头文件 <memory>:
#include <memory>
#include <iostream>
using namespace std;
class A {
int size;
char *p;
public:
A(int s=1):size(s){cout<<"构造"<<endl; p = new char[s];}
~A(){cout<<"析构"<<endl; delete [] p;}
void resize(int newSize) { // 重新分配堆内存
size = newSize;
delete [] p;
p = new char[size];
}
void info(void){cout << size << endl;} // 输出大小
};
void someFunction(void) {
auto_ptr<A> ap(new A(20)); // 封装原始指针
ap->info(); // 等价于 (*ap).info(),输出 20
ap->resize(100); // 操作资源
ap->info(); // 输出 100
} // 离开作用域,ap 析构,自动释放 A 对象资源
// 执行结果:
// 构造
// 20
// 100
// 析构
核心缺陷(废弃原因)
auto_ptr 支持拷贝构造和赋值运算,但会导致原指针失去资源控制权(逻辑与语法矛盾),编译器无语法限制,极易踩坑:
void someFunction(void) {
auto_ptr<A> sp1(new A(20));
auto_ptr<A> sp2(sp1); // 拷贝构造:sp1 失去控制权
sp1->info(); // 异常!sp1 已失效
auto_ptr<A> sp3;
sp3 = sp2; // 赋值运算:sp2 失去控制权
sp2->info(); // 异常!sp2 已失效
sp3->resize(666); // 仅最后一个指针有效
sp3->info(); // 正常输出 666
}
结论:auto_ptr 仅能单独使用,禁止拷贝构造和赋值操作,因设计缺陷被 C++17 废弃,不推荐使用。
