zoukankan      html  css  js  c++  java
  • 智能指针——学习与应用

    //TO DO

    //
    //  main.cpp
    //  learn_smart_point
    //
    //  Created by New_Life on 2017/8/19.
    //  Copyright © 2017年 chenhuan001. All rights reserved.
    //
    
    #include <iostream>
    #include <vector>
    #include <memory>//the head file of smart point
    
    class TestBase {
    public:
        TestBase() {
            std::cout << "TestBase construct" << std::endl;
        }
    
        ~TestBase() {
            std::cout << "TestBase destroy" << std::endl;
        }
        
        void print_info() {
            std::cout << "TestBase print_info : " << info.c_str() << std::endl;
        }
        
        void set_info(std::string str) {
            info = str;
        }
        
        std::string info;
    };
    
    class TestEqual : public TestBase {
    public:
        TestEqual() {}
        ~TestEqual() {}
        TestEqual& operator = (int a) {
            std::cout << "in operatr = with int" << std::endl;
            return *this;
        }
        
        void operator = (bool a) {
            std::cout << "in operatr = with return void" << std::endl;
            //return *this;
            return ;
        }
    };
    
    class DebugInfo {
    public:
        DebugInfo(const char* info) {
            _info = info;
            std::cout << "------in " << _info.c_str() << "------" << std::endl;
        }
        
        ~DebugInfo() {
            std::cout << "------out " << _info.c_str() << "------" << std::endl;
        }
        
    private:
        std::string _info;
    };
    
    void test_equal() {
        DebugInfo debug_auto_ptr("test_equal");
        TestEqual test_equal;
        test_equal = 1;
        test_equal = true;
        TestEqual test_equal1;
        //test_equal1 = test_equal = false;//whill compile fail
        test_equal1 = test_equal;//默认赋值函数还是存在的
    }
    
    void test_auto_ptr() {
        DebugInfo debug_auto_ptr("test_auto_ptr");
        
        std::auto_ptr<TestBase> base(new TestBase());//封装了下。然后呢
    }
    
    
    int main(int argc, const char * argv[]) {
        //test_equal();
        test_auto_ptr();
        return 0;
    }

    1. std::auto_ptr源码分析

    template <class _Tp> class auto_ptr {
    private:
      _Tp* _M_ptr;
    
    public:
      typedef _Tp element_type; //在类内部typedef
    
      explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {} //use default argument and nothrow
      auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} //哇 拷贝构造函数里面,直接把之前的release掉了。
    
      auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { //赋值函数也是如此。
        if (&__a != this) {
          delete _M_ptr;//直接把原来的delete
          _M_ptr = __a.release();
        }
        return *this;
      }
    
      ~auto_ptr() __STL_NOTHROW { delete _M_ptr; }
    
      _Tp& operator*() const __STL_NOTHROW {
        return *_M_ptr;
      }
      _Tp* operator->() const __STL_NOTHROW {//神奇的用法。
        return _M_ptr;
      }
      _Tp* get() const __STL_NOTHROW {
        return _M_ptr;
      }
      _Tp* release() __STL_NOTHROW {
        _Tp* __tmp = _M_ptr;
        _M_ptr = 0;
        return __tmp;
      }
      void reset(_Tp* __p = 0) __STL_NOTHROW {
        if (__p != _M_ptr) {
          delete _M_ptr;
          _M_ptr = __p;
        }
      }
    #endif /* auto ptr conversions && member templates */
    };

    上述源码很清晰的说明了auto_ptr的原理。

    auto_ptr是在普通的指针上封装了一层,用于管理指针。

    构造时传入一个指针,析构是将这个指针delete。

    在进行赋值,或者函数参数传递的过程中。会立即把自身保存的指针release掉。

    而release是把当前类保存的指针传出去,然后清空。

    所以使用auto_ptr会有以下几个问题:

    1. 直接调用release后,因为realse本身不会释放保存的指针内存,所以会造成内存泄露。

    2. 唯一传递性,传递给其他auto_ptr对象,当前的对象就不在拥有对该指针的控制权。

    2. boost::scoped_ptr源码分析

    template<class T> class scoped_ptr // noncopyable
    {
    private:
    
        T * px;
    
        scoped_ptr(scoped_ptr const &);
        scoped_ptr & operator=(scoped_ptr const &);
    
        typedef scoped_ptr<T> this_type;
    
        void operator==( scoped_ptr const& ) const;
        void operator!=( scoped_ptr const& ) const;
    
    public:
    
        typedef T element_type;
    
        explicit scoped_ptr( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p ) // never throws
        {
    #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
            boost::sp_scalar_constructor_hook( px );
    #endif
        }
    
    #ifndef BOOST_NO_AUTO_PTR
    
        explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
        {
    #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
            boost::sp_scalar_constructor_hook( px );
    #endif
        }
    
    #endif
    
        ~scoped_ptr() // never throws
        {
    #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
            boost::sp_scalar_destructor_hook( px );
    #endif
            boost::checked_delete( px );
        }
    
        void reset(T * p = 0) // never throws
        {
            BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
            this_type(p).swap(*this);
        }
    
        T & operator*() const // never throws
        {
            BOOST_ASSERT( px != 0 );
            return *px;
        }
    
        T * operator->() const // never throws
        {
            BOOST_ASSERT( px != 0 );
            return px;
        }
    
        T * get() const BOOST_NOEXCEPT
        {
            return px;
        }
    
    // implicit conversion to "bool"
    #include <boost/smart_ptr/detail/operator_bool.hpp>
    
        void swap(scoped_ptr & b) BOOST_NOEXCEPT
        {
            T * tmp = b.px;
            b.px = px;
            px = tmp;
        }
    };

    相对于std::auto_ptr

    boost::scoped_ptr将拷贝构造函数与赋值重载函数设为私有的,也就禁止了拷贝的情况。也就是不会有std::auto_ptr中的问题2.

    因为没有了拷贝的情况,所以boost::scoped_ptr不带有release,所以也不会有std::auto_ptr中的问题1.

    但是scoped_ptr的用法就很局限了,只能在作用范围内使用。不允许交换控制权。

  • 相关阅读:
    洛谷 P1194 飞扬的小鸟 题解
    洛谷 P1197 星球大战 题解
    洛谷 P1879 玉米田Corn Fields 题解
    洛谷 P2796 Facer的程序 题解
    洛谷 P2398 GCD SUM 题解
    洛谷 P2051 中国象棋 题解
    洛谷 P1472 奶牛家谱 Cow Pedigrees 题解
    洛谷 P1004 方格取数 题解
    洛谷 P2331 最大子矩阵 题解
    洛谷 P1073 最优贸易 题解
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/7396112.html
Copyright © 2011-2022 走看看