所谓智能指针,就是可以随便申请而无需管理自动释放,就像 java 或 C# 的垃圾回收机制一样。我们无需关心销毁只管尽情的申请,系统提供了一个 auto_ptr 类可以使用这样的功能。后面我们也会用简单的代码示例介绍 auto_ptr 内部是如何实现的。代码如下:
#include <iostream> #include <memory> using namespace std; class A { public: A(){cout << "A constructor" << endl;}; ~A(){cout << "A destructor" << endl;}; }; void foo() { auto_ptr<A> p(new A); } int main(int argc, char* argv[]) { foo(); return 0; }
以上代码运行后,如下图:
从图中我们可以看到,我们只做了申请操作,而并未对new出来的指针进行销毁,为什么会打印类 A 的析构函数中的内容呢?其实想搞清楚这件事情并不难,请大家看如下代码,并仔细查看我所做的注释:
#include <iostream> #include <memory> using namespace std; class A { public: A() { cout << "A constructor" << endl; } ~A() { cout << "A destructor" << endl; } void display() { cout << "are you ok?" << endl; } private: }; class SPA { public: // 构造函数中创建一个A类的对象指针 SPA(A* p) :_p(p) { cout << "SPA" << endl; } // 析构的时候将指针销毁 ~SPA() { cout << "~SPA" << endl; delete _p; } // 重载->,让构造出来的对象可以直接使用->运算符 A* operator->() { return _p; } // 重载*,可以对构造出来的对象解引用 A& operator*() { return *_p; } private: A* _p; }; void foo() { // 构造一个SPA对象,传递一个A的指针 SPA ptr(new A); // 调用重载的->运算符 ptr->display(); // 调用重载的*运算符 (*ptr).display(); // 出栈后让栈上的SPA对象析构 // 调用了析构函数,所以会自动销毁A对象指针所指向的内存 } int main(int argc, char* argv[]) { foo(); return 0; }
实际看完代码你可以发现,我们利用了函数压栈和出栈时将栈上对象弹出后调用析构函数的逻辑,让栈上的对象 SPA 在出栈的时候自动调用析构函数将类 A 所申请的内存销毁掉,这样绝妙的手段真的是难以想想,C++奥妙无穷,后面你会看到更多好玩的东西。