C++智能指针:auto-ptr详解.pdf
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
C++智能指针:auto_ptr详解 指针,相信⼤家并不陌⽣。⽆论是我们在进⾏查看内存还是在修改字符串,我们都会⽤到指针。 最常见的情况则是我们使⽤malloc或者new申请到了⼀块内存,然后⽤⼀个指针来保存起来。我们都知道有内存的申请那就必须要对它进⾏ 释放的处理,否则会造成最严重的后果——内存泄漏。⼀个或者两个申请的内存我们或许不会忘记去释放,但是如果成千上万⾏代码,你还 能记得住哪个释放了哪个没有释放吗? ⽽智能指针就是为了解决这个问题⽽产⽣的。最开始智能指针是在boost库中的,随着时间发展现在已经成为了C11的特性。(虽然我们本 篇要介绍的最基础的auto_ptr在C++11中已经被unique_ptr替代了。。) 智能指针的基本原理 智能指针其实是⼀个类,可以通过将普通指针作为参数传⼊智能指针的构造函数实现绑定。只不过通过运算符重载让它"假装"是⼀个指 针,也可以进⾏解引⽤等操作。既然智能指针是⼀个类,对象都存在于栈上,那么创建出来的对象在出作⽤域的时候(函数或者程序结束)会 ⾃⼰消亡,所以在这个类中的析构函数中写上delete就可以完成智能的内存回收。 Auto_ptr详解 使⽤时,需要包含头⽂件:memory。 auto_ptr,作为智能指针的始祖,能基本实现我们所期望的功能。⽽且设计简单源码易懂,虽然缺陷众多,但作为了解智能指针的研究对象 还是⼗分合适的。 ⾸先我们先来写⼀个测试类⽤于分析。 #include <iostream> #include <memory> using namespace std; class Test { public: Test(int param = 0) //调⽤时,可以指定是第⼏个对象。默认第0个 { num = param; cout << "Simple:" << num << endl; } ~Test() //析构时会指出第⼏个对象被析构。 { cout << "~Simple:" << num << endl; } void PrintSomething() //输出附加的字符串⽅法。 { cout << "PrintSomething:" << info_extend.c_str() << endl; } int num; //代表这个对象的序号。 string info_extend; //附加的字符串。 }; 接下来,我们通过⼏个测试函数来实验⼀下auto_ptr的基本功能,再来了解⼀下它的弊端。 I.Auto_ptr的基本功能 的基本功能 void TestAutoPtr1() { auto_ptr<Test> my_auto (new Test(1)); //绑定⼀个Test类的新建对象 if(my_auto.get()) //get函数⽤来显式返回它拥有的对象指针,此处判⾮空 { my_auto->PrintSomething(); my_auto.get()->info_extend = "Addition"; //对类内成员进⾏操作 my_auto->PrintSomething(); //看是否成功操作 (*my_auto).info_extend += " other"; //实验解引⽤操作 mt_auto->PrintSomething(); } } 运⾏结果: 我们可以看到在绑定时输出Simple:1,之后也能正常实现Test类中的功能,同时my_auto可以通过get⽅法进⾏裸指针赋值以及使⽤*进⾏ 解引⽤操作,与普通指针⽆异。最后函数结束后,在调⽤析构函数的同时auto_ptr的析构函数也将Test类的对象delete掉,我加⼊的内存泄 漏探测⼯具也显⽰No memory leaks detected(没有检查测到内存泄漏). II.Auto_ptr的弊端 的弊端1 void TestAutoPtr2() { auto_ptr<Test> my_auto1 (new Test(1)); if(my_auto1.get()) { (*my_auto1).info_extend = "Test"; //先赋予⼀个初始值作为区别两个指针的标志 auto_ptr<Test> my_auto2; my_auto2 = my_auto1; my_auto2->PrintSomething(); //打印发现成功转移 my_auto1->PringSomething(); //崩溃 } } 在这个程序的最后⼀步会崩溃,罪魁祸⾸就是my_auto2 = my_auto1语句。 autp_ptr对赋值运算符重载的实现是reset(Myptr.release()),即reset和release函数的组合。release会释放所有权,reset则是⽤于接受 C++智能指针是编程语言中用于自动化内存管理的重要工具,它们主要负责自动释放动态分配的内存,防止内存泄漏。本文将深入探讨C++中的`auto_ptr`,一种早期的智能指针,尽管在C++11标准中已被`unique_ptr`取代,但它仍然是理解智能指针工作原理的良好起点。 智能指针的基础原理在于,它是一个类,能够通过构造函数绑定到一个原始指针。`auto_ptr`也不例外,它模拟了指针的行为,允许解引用和成员访问。当`auto_ptr`对象离开作用域(通常是函数结束时),其析构函数会自动调用`delete`来释放绑定的内存。这种机制使得程序员无需手动管理内存,降低了因忘记释放内存而引发的潜在问题。 在C++中,`<memory>`头文件包含了`auto_ptr`的相关定义。下面我们将详细讨论`auto_ptr`的使用和局限性。 **I. `auto_ptr`的基本功能** 在`TestAutoPtr1`函数中,我们创建了一个`auto_ptr<Test>`实例`my_auto`并用`new`操作符动态分配了一个`Test`对象。`my_auto`可以像普通指针一样进行解引用操作,并且`get()`函数提供了获取绑定对象原始指针的能力。当函数结束时,`my_auto`自动析构,释放其所管理的`Test`对象,确保没有内存泄漏。 **II. `auto_ptr`的弊端** 然而,`auto_ptr`的一个主要问题是它的赋值行为。在`TestAutoPtr2`函数中,我们看到当尝试将一个`auto_ptr`赋值给另一个时,原始`auto_ptr`(`my_auto1`)会失去对其对象的所有权,导致对象被提前删除。这是因为`auto_ptr`的赋值运算符执行了`reset()`和`release()`的操作,前者接受`release()`返回的原始指针并删除旧的指针。这意味着一旦`auto_ptr`被赋值,之前的对象就会被释放,可能导致未预期的程序崩溃。 由于这个危险的特性,C++11引入了`unique_ptr`,它不支持直接赋值操作,而是通过`std::move`来转移所有权,从而避免了`auto_ptr`的这种陷阱。 总结来说,`auto_ptr`是C++早期智能指针的尝试,它实现了基本的自动内存管理,但其设计上的缺陷(尤其是赋值操作)使其在C++11后逐渐被淘汰。尽管如此,学习`auto_ptr`有助于理解智能指针的基本概念,以及为何现代C++推荐使用`unique_ptr`、`shared_ptr`等更安全的智能指针类型。在实际开发中,为了确保内存安全和程序稳定性,应优先考虑使用C++11及以后版本推荐的智能指针。
- 粉丝: 195
- 资源: 3万+
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助