2005년 12월 22일 목요일

[펌] shared_ptr 사용법

 

shared_ptr

  • new 를 해주고 delete 하는 것 에서 해방을!
  • 표준 라이브러리에도 auto_ptr 이라고 같은 개념의 클래스가 있지만, 버그가 있다. -_-;; auto_ptr를 컨테이너에 집어넣으면 버그땜시 스스로 삭제가 안되 메모리가 새는 아주 심각한 문제이다.
... 
#include <boost/smart_ptr.hpp> 
... 
using namespace boost; 
... 
class Vertex3D {...} 
typedef shared_ptr<Vertex3D> Vertex3DSPtr; 
typedef vector<Vertex3DSPtr> Vertexs; // 단어 틀렸다는거 알지만 그냥 씀 -_- 
typedef Vertexs::size_type VertexsSize; 
typedef Vertexs::iterator VertexsItr; 
typedef shared_ptr<Vertexs> VertexsSPtr; 
... 
{ 
  VertexsSPtr vertexs(new Vertexs); 
  Vertex3DSPtr vertex(new Vertex3D); 
  ... 
  vertexs->push_back(vertex); 
  ... 
} 
  • new 를 했지만 delete 를 안해도 지가 알아서 사라진다.
  • 모든 객체에 스마트포인터를 쓰도록 프로그램 짜면 자바같은 느낌으로 짤수도 ...

shared_ptr_example

shared_ptr_example.cpp
//  Boost shared_ptr_example.cpp  --------------------------------------------// 
 
//  (C) Copyright Beman Dawes 2001. 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. 
 
//  See http://www.boost.org for most recent version including documentation. 
 
//  Revision History 
//  21 May 01  Initial complete version (Beman Dawes) 
 
//  The original code for this example appeared in the shared_ptr documentation. 
//  Ray Gallimore pointed out that foo_set was missing a Compare template 
//  argument, so would not work as intended.  At that point the code was 
//  turned into an actual .cpp file so it could be compiled and tested. 
 
#include <vector> 
#include <set> 
#include <iostream> 
#include <algorithm> 
#include <boost/shared_ptr.hpp> 
 
//  The application will produce a series of 
//  objects of type Foo which later must be 
//  accessed both by occurrence (std::vector) 
//  and by ordering relationship (std::set). 
 
struct Foo 
{ 
  Foo( int _x ) : x(_x) {} 
  ~Foo() { std::cout << "Destructing a Foo with x=" << x << "\n"; } 
  int x; 
  /* ... */ 
}; 
 
typedef boost::shared_ptr<Foo> FooPtr; 
 
struct FooPtrOps 
{ 
  bool operator()( const FooPtr & a, const FooPtr & b ) 
    { return a->x > b->x; } 
  void operator()( const FooPtr & a ) 
    { std::cout << a->x << "\n"; } 
}; 
 
int main() 
{ 
  std::vector<FooPtr>         foo_vector; 
  std::set<FooPtr,FooPtrOps>  foo_set; // NOT multiset! 
 
  FooPtr foo_ptr( new Foo( 2 ) ); 
  foo_vector.push_back( foo_ptr ); 
  foo_set.insert( foo_ptr ); 
 
  foo_ptr.reset( new Foo( 1 ) ); 
  foo_vector.push_back( foo_ptr ); 
  foo_set.insert( foo_ptr ); 
 
  foo_ptr.reset( new Foo( 3 ) ); 
  foo_vector.push_back( foo_ptr ); 
  foo_set.insert( foo_ptr ); 
 
  foo_ptr.reset ( new Foo( 2 ) ); 
  foo_vector.push_back( foo_ptr ); 
  foo_set.insert( foo_ptr ); 
 
  std::cout << "foo_vector:\n"; 
  std::for_each( foo_vector.begin(), foo_vector.end(), FooPtrOps() ); 
 
  std::cout << "\nfoo_set:\n"; 
  std::for_each( foo_set.begin(), foo_set.end(), FooPtrOps() ); 
  std::cout << "\n"; 
 
//  Expected output: 
// 
//   foo_vector: 
//   2 
//   1 
//   3 
//   2 
// 
//   foo_set: 
//   3 
//   2 
//   1 
// 
//   Destructing a Foo with x=2 
//   Destructing a Foo with x=1 
//   Destructing a Foo with x=3 
//   Destructing a Foo with x=2 
 
  return 0; 
} 

shared_ptr_example2

shared_ptr_example2.hpp (헉 이너클래스가 되네.. 처음봤다 --;;)
//  Boost shared_ptr_example2 header file  -----------------------------------// 
 
#include <boost/shared_ptr.hpp> 
 
//  This example demonstrates the handle/body idiom (also called pimpl and 
//  several other names).  It separates the interface (in this header file) 
//  from the implementation (in shared_ptr_example2.cpp). 
 
//  Note that even though example::implementation is an incomplete type in 
//  some translation units using this header, shared_ptr< implementation > 
//  is still valid because the type is complete where it counts - in the 
//  shared_ptr_example2.cpp translation unit where functions requiring a 
//  complete type are actually instantiated. 
 
class example 
{ 
 public: 
  example(); 
  example( const example & ); 
  example & operator=( const example & ); 
  void do_something(); 
 private: 
  class implementation; 
  boost::shared_ptr< implementation > _imp; // hide implementation details 
}; 

shared_ptr_example2.cpp

// Boost shared_ptr_example2 implementation file  -----------------------------// 
 
#include "shared_ptr_example2.hpp" 
#include <iostream> 
 
class example::implementation 
{ 
 public: 
  ~implementation() { std::cout << "destroying implementation\n"; } 
}; 
 
example::example() : _imp( new implementation ) {} 
example::example( const example & s ) : _imp( s._imp ) {} 
 
example & example::operator=( const example & s ) 
  { _imp = s._imp; return *this; } 
 
void example::do_something() 
  { std::cout << "use_count() is " << _imp.use_count() << "\n"; } 

shared_ptr_example2_test.cpp

// Boost shared_ptr_example2_test main program  ------------------------------// 
 
#include "shared_ptr_example2.hpp" 
 
int main() 
{ 
  example a; 
  a.do_something(); 
  example b(a); 
  b.do_something(); 
  example c; 
  c = a; 
  c.do_something(); 
  return 0; 
} 

댓글 없음:

댓글 쓰기