c++中如果要申请资源一般用到new,最后释放资源delete,如果我们在delete之前就退出了函数呢,看下面的代码:
- #include <iostream>
- //#include <memory>
- using namespace std;
- void fun()
- {
- int *ptr = new int;
- if(ptr == 0)
- {
- delete ptr;
- return;
- }
- cout << "hello prt" << endl;
- delete ptr;
- }
- int main()
- {
- fun();
- return 0;
- }
这样我们就要多写一个delete,如果if有很多分支或者别情况呢。甚至有时候我们忘了delete呢,他将导致内存泄露。如果使用智能指针auto_ptr就不会出现这种情况了。
下面我们来看一个例子:
- #include <iostream>
- #include <memory>//auto_ptr 需要用到的头文件
- using namespace std;
- void fun(auto_ptr<int> ptr)
- {
- if (ptr.get() == NULL)
- {
- cout << "NULL" << endl;
- }
- else
- {
- cout << *ptr << endl;
- }
- }
- int main()
- {
- auto_ptr<int> ptr(new int);
- //auto_ptr<int> ptr = new int(11); //ERROR 注意智能指针不能使用这种赋值方式
- *ptr = 44;
- fun(ptr);
- //cout << *ptr << endl;
- if (ptr.get() == NULL)
- {
- cout << "delete" << endl;
- }
- return 0;
- }
编译后结果为 44 delete
很明显我们可以看到ptr被释放掉了。
注意,智能指针有拥有权转移的性质,ptr1给ptr2赋值后,ptr1就被delete掉了就不能再取他的值了。代码如下:
- #include <iostream>
- #include <memory>
- using namespace std;
- ostream& operator<< (ostream& otm , auto_ptr<int>& ptr)
- {
- if(ptr.get() == NULL)
- {
- otm << "NULL" << endl;
- }
- else
- {
- otm << *ptr << endl;
- }
- return otm;
- }
- int main()
- {
- auto_ptr<int> ptr1(new int(22));
- auto_ptr<int> ptr2;
- cout << ptr1 << endl;
- cout << ptr2 << endl;
- ptr2 = ptr1;
- cout << ptr1 << endl;
- cout << ptr2 << endl;
- return 0;
- }
编译后结果为22 NULL NULL 22
可以看到执行ptr2 = ptr1后ptr1指向了NULL。
如果我们不希望看到拥有权的改变那就要在声明是加const。拥有权不可以改变但你可以取他的值来赋值,例如:*ptr1 = * prt2。
下面附一份《c++标准程序库》中提供的auto_ptr的实现代码,看了下,跟《c++程序设计语言》中的差不多,但跟具体,据说比标准库的有一些改进。
- /* The following code example is taken from the book
- * "The C++ Standard Library - A Tutorial and Reference"
- * by Nicolai M. Josuttis, Addison-Wesley, 1999
- *
- * (C) Copyright Nicolai M. Josuttis 1999.
- * Permission to copy, use, modify, sell and distribute this software
- * is granted provided this copyright notice appears in all copies.
- * This software is provided "as is" without express or implied
- * warranty, and with no claim as to its suitability for any purpose.
- */
- /* class auto_ptr
- * - improved standard conforming implementation
- */
- namespace std {
- // auxiliary type to enable copies and assignments (now global)
- template<class Y>
- struct auto_ptr_ref {
- Y* yp;
- auto_ptr_ref (Y* rhs)
- : yp(rhs) {
- }
- };
- template<class T>
- class auto_ptr {
- private:
- T* ap; // refers to the actual owned object (if any)
- public:
- typedef T element_type;
- // constructor
- explicit auto_ptr (T* ptr = 0) throw()
- : ap(ptr) {
- }
- // copy constructors (with implicit conversion)
- // - note: nonconstant parameter
- auto_ptr (auto_ptr& rhs) throw()
- : ap(rhs.release()) {
- }
- template<class Y>
- auto_ptr (auto_ptr<Y>& rhs) throw()
- : ap(rhs.release()) {
- }
- // assignments (with implicit conversion)
- // - note: nonconstant parameter
- auto_ptr& operator= (auto_ptr& rhs) throw() {
- reset(rhs.release());
- return *this;
- }
- template<class Y>
- auto_ptr& operator= (auto_ptr<Y>& rhs) throw() {
- reset(rhs.release());
- return *this;
- }
- // destructor
- ~auto_ptr() throw() {
- delete ap;
- }
- // value access
- T* get() const throw() {
- return ap;
- }
- T& operator*() const throw() {
- return *ap;
- }
- T* operator->() const throw() {
- return ap;
- }
- // release ownership
- T* release() throw() {
- T* tmp(ap);
- ap = 0;
- return tmp;
- }
- // reset value
- void reset (T* ptr=0) throw() {
- if (ap != ptr) {
- delete ap;
- ap = ptr;
- }
- }
- /* special conversions with auxiliary type to enable copies and assignments
- */
- auto_ptr(auto_ptr_ref<T> rhs) throw()
- : ap(rhs.yp) {
- }
- auto_ptr& operator= (auto_ptr_ref<T> rhs) throw() { // new
- reset(rhs.yp);
- return *this;
- }
- template<class Y>
- operator auto_ptr_ref<Y>() throw() {
- return auto_ptr_ref<Y>(release());
- }
- template<class Y>
- operator auto_ptr<Y>() throw() {
- return auto_ptr<Y>(release());
- }
- };
- }
FROM: http://blog.csdn.net/z0203153008/article/details/4652046