Loading... ## 引言 new 分配的内存块与常规变量声明分配的内存块不同,常规变量声明分配的内存在被称为栈的内存区域中,而new在被称为堆(也称自由存储区)的内存区域分配内存。 直接声明的对象,比如 BinNode a,即在栈上面的对象,所在作用域结束后,栈空,然后会自动执行析构函数,而new创建出来的是在堆上的对象,如果不调用delete,即使它所在的作用域已经结束,也不会调用析构函数。系统os 会在程序结束,回收该部分内存。  ## 简介 auto_ptr、unique_ptr、shared_ptr 这三个智能指针模版都定义了类似指针的对象,可以将new获得的地址赋值给这种对象。当智能指针过期时,会自动调用指针对象的析构函数,再释放堆中内存。其也相当于等价delete操作。也就是说,delete语句的本质是调用指针对象自身的析构函数,再释放内存。与之对应,new的本质是先在堆上分配内存,再调用对象的构造函数。 所有权概念: 对于特定的对象,只能有一个智能指针拥有它,这样只有拥有对象所有权的智能指针的析构函数会删除该对象。(不适用于shared_ptr) ## 使用 要创建智能指针对象,必须包含头文件`memory`。 * auto_ptr等三个智能指针都可以自动调用析构函数。 * auto_ptr已过时,不被推荐使用。 * unique_ptr 用于代替auto_ptr。其特点是不允许智能指针赋值,保护所有权。 * 如果程序要使用多个指向同一对象的指针,应选用shared_ptr。 ## 代码实例 ```cpp #include <iostream> #include <memory> #include <string> class Report { private: std::string str; public: Report(const std::string s) : str(s) { std::cout << "object created\n"; } ~Report() { std::cout << "object deleted!\n"; } void comment() const { std::cout << str << "\n"; } }; int main() { { Report a(" not using new"); a.comment(); } std::cout << "--------------------\n"; { //加括号是为了限制定义域,出了定义域就应该删除内部临时变量。 Report* pr = new Report("using simple ptr"); // 发现一个知识,通过new 建立的内存块 是必须要用delete 语句来释放的,换而言之,其实,new 没有创建一个Report只是创建了一个Report* ,他是不会在程序结束后自动调用 其析构函数的。 pr->comment(); } std::cout << "--------------------\n"; { std::auto_ptr<Report> ps(new Report("using auto_ptr")); ps->comment(); } std::cout << "--------------------\n"; { std::unique_ptr<Report> p(new Report("using unique_ptr")); p->comment(); } return 0; } ``` 输出 ```c object created not using new object deleted! -------------------- object created using simple ptr 可以看出没有调用析构函数,当然也没有释放内存 -------------------- object created using auto_ptr object deleted! -------------------- object created using unique_ptr object deleted! ``` ## 参考文章 https://www.cnblogs.com/chenmingjun/p/8283374.html 最后修改:2020 年 12 月 10 日 08 : 29 PM © 允许规范转载