智能指针是什么?能否为?

摘要:基本概念 问题背景 在 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 废弃,不推荐使用。
阅读全文