SyntaxHighlighter

2009/06/17

いまさらsmart pointer

いまさらBoostのスマートポインタを使っています。
全てのクラスを下記の派生クラスにしてしまうと、非常に楽かなぁと思い、メモ。
#include <boost/intrusive_ptr.hpp>
#include <boost/detail/atomic_count.hpp>
namespace smart_ptr
{
  class smart_ptr_object
  {
  private:
    friend void intrusive_ptr_add_ref( const smart_ptr_object * o ) // This is not a member function
    {
      ++o->m_ref_counter;
    }

    friend void intrusive_ptr_release( const smart_ptr_object * o ) // This is not a member function
    {
      if (--o->m_ref_counter == 0)
      {
        delete const_cast<smart_ptr_object*>(o);
      }
    }

    // Define the following type for each sub class in public scope
    typedef boost::intrusive_ptr<smart_ptr_object> pointer_t;

    // reference counter for intrusive_ptr
    mutable boost::detail::atomic_count m_ref_counter;

  public:
    smart_ptr_object() : m_ref_counter(0) {}

    virtual ~smart_ptr_object() {}
  };// class smart_ptr_object
} // namespace smart_ptr


次に自前のクラス、例えば、
class test_obj : public smart_ptr::smart_ptr_object
{
private:
  std::string m_str;

public:

  test_obj(const std::string & str) : m_str(str)
  {
    std::cout << "Constructor: " << m_str << " [" << this << "]" << std::endl;
  }
  ~test_obj()
  {
    std::cout << "Destructor:  " << m_str << " [" << this << "]" << std::endl;
  }

  const std::string get() const
  {
    return m_str;
  }

  typedef boost::intrusive_ptr<test_obj> pointer_t;
}; //class test_obj : pulbic smart_ptr_object

のようなクラスを作成します。ただし、最後にtypedefは自分で定義する必要があります。

そして、
int main( int argc, char * argv[] )
{
  test_obj::pointer_t sp1( new test_obj("sp1") );
  std::cout << sp1->get() << std::endl;

  test_obj::pointer_t sp2( new test_obj("sp2") );
  std::cout << sp2->get() << std::endl;

  sp2 = 0;

  test_obj::pointer_t sp3 = getNewObj("sp3");
  std::cout << sp3->get() << std::endl;

  return 0;
}

のように呼び出すと、Beyond the C++ Standard Library: An Introduction to Boost
Constructor: sp1 [00395D10]
sp1
Constructor: sp2 [00395DE0]
sp2
Destructor:  sp2 [00395DE0]
Constructor: sp3 [00395DE0]
sp3
Destructor:  sp3 [00395DE0]
Destructor:  sp1 [00395D10]
というような結果になる。

newとdelete演算子を繰り返したくなければ、Boost Pool Libraryを使うことができるんじゃないかと思う。

0 件のコメント: