ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
C++11 SMART POINTERS
@mine260309
? Overview
? shared_ptr
? unique_ptr
? weak_ptr
¨C Cyclic reference problem
¨C Enable shared from this
? Miscs
AGENDA
? std::shared_ptr
¨C shared ownership
? std::unique_ptr
¨C unique ownership
? std::weak_ptr
¨C No ownership
? NO std::intrusive_ptr
OVERVIEW
? boost::shared_ptr
¨C shared ownership
? boost::scoped_ptr
¨C unique ownership
? boost::weak_ptr
¨C No ownership
¡Ö
Differences:
? Compiler (C++11 vs C++03)
? Move-Semantic
? std::unique_ptr supports transfer-of-ownership
? boost::scoped_ptr is neither copyable nor movable
? Array support (See details in Miscs)
std::shared_ptr
? Features
¨C share ownership
¨C reference count
¨C auto delete
¨C native inheritance
¨C cast
? Overhead
¨C Manager-Object*
¨C Managed-Object-T*
¨C Lock of increment/decrement of reference count (Thread safe)
SHARED_PTR
shared_ptr<T>
Manager
Object*
T*
Reference
Counted with
Lock
Object T
? Refer to objects allocated with new and can be deleted with
delete
? Create by new or make_shared
¨C shared_ptr<T> t(new T(¡­));
¨C shared_ptr<T> t(make_shared<T>(¡­));
? Try hard to avoid using raw pointers
¨C Mixing smart and built-in pointers can be hard to get right
? Then never explicitly call delete
RULES OF SHARED_PTR
? shared_ptr<T> t(new T(¡­));
¨C Two dynamic allocations
? shared_ptr<T> t(make_shared<T>(¡­));
¨C Single dynamic allocation
? Why?
¨C Manager-Object*
¨C Managed-Object-T*
? Prefer ::make_shared if a lof of shared_ptrs are created
MAKE_SHARED VS NEW
shared_ptr<T>
Manager
Object*
T*
Reference
Counted with
Lock
Object T
? http://ideone.com/aEFxlk
BASIC USE OF SHARED_PTR
std::shared_ptr<TClass> c2(new TClass(2)); // TClass 2
std::shared_ptr<TClass> c3 = std::make_shared<TClass>(3);
std::shared_ptr<TClass> c4; // Empty shared_ptr
c4.reset(new TClass(4)); // TClass: 4
if (c4) {
... // Do something
}
c4.reset(); // c4 becomes empty
if (c4) { // Now it returns false
... // Code does not go here
}
? Same as raw pointer
? http://ideone.com/jp4iCI
INHERITANCE OF SHARED_PTR
std::shared_ptr<TDerived> dp1(new TDerived);
std::shared_ptr<TBase> bp1 = dp1;
std::shared_ptr<TBase> bp2(dp1);
std::shared_ptr<TBase> bp3(new TDerived);
? Similar with raw pointer
¨C static_pointer_cast
¨C dynamic_pointer_cast
¨C const_pointer_cast
? Create a new shared_ptr!
? http://ideone.com/TdcPDl
CASTING SHARED_PTR
std::shared_ptr<TBase> bp1(new TDerived);
std::shared_ptr<const TBase> cbp(new TBase);
std::shared_ptr<TDerived> dp1 = std::static_pointer_cast<TDerived>(bp1);
std::shared_ptr<TDerived> dp2 = std::dynamic_pointer_cast<TDerived>(bp1);
std::shared_ptr<TBase> bp2 = std::const_pointer_cast<TBase>(cbp);
//std::shared_ptr<TDerived> d = static_cast<std::shared_ptr<TDerived>>(bp1);
// Compile error
std::unique_ptr
? Features
¨C Unique ownership
? Copy constructor and copy assignment = delete
¨C No reference count
¨C auto delete
¨C native inheritance
¨C No cast, or manually cast
? Overhead
¨C Nothing!
? Rules?
¨C The same as shared_ptr
UNIQUE_PTR
? new or std::move (transfer ownership)
? http://ideone.com/bxsFvC
BASIC USE OF UNIQUE_PTR
std::unique_ptr<TClass> c2(new TClass(2));
std::unique_ptr<TClass> c3; // Empty unique_ptr
//c3 = c2; // error: use of deleted function operator=()
c3 = std::move(c2); // unique_ptr has to be moved
// Now c2 owns nothing
// Note that return value of a function is a rvalue
std::unique_ptr<TClass> GetATClass() {
std::unique_ptr<TClass> c(new TClass(0));
return c; // same as `return std::move(c);`
}
c3 = GetATClass();
? Same as raw pointer
? http://ideone.com/FhgRi9
INHERITANCE OF UNIQUE_PTR
std::unique_ptr<TDerived> dp1(new TDerived);
std::unique_ptr<TBase> bp1 = std::move(dp1);
std::unique_ptr<TBase> bp2(std::move(bp1));
std::unique_ptr<TBase> bp3(new TDerived);
? Generally, do NOT cast
? Why no native cast?
¨C Cast makes a copy of the pointer
? But I do want to cast unique_ptr?
? http://ideone.com/F8CfIG
CAST(MANUALLY) OF UNIQUE_PTR
std::unique_ptr<TBase> bp1(new TDerived);
std::unique_ptr<TDerived> dp1(static_cast<TDerived*>(bp1.get()));
bp1.release(); // Now bp1 owns nothing
bp1 = std::move(dp1); // Transfer ownership to bp1 (inheritance)
std::unique_ptr<TDerived> dp2(dynamic_cast<TDerived*>(bp1.get()));
bp1.release(); // Now bp1 owns nothing
std::weak_ptr
? ¡°Observe¡± the managed object
? Provide a shared_ptr when used
? Why?
¨C Solve cyclic reference of shared_ptr
¨C Helps to get a shared_ptr from ¡°this¡±
WEAK_PTR
? http://ideone.com/tZ3ZhJ
BASIC USE OF WEAK_PTR
std::weak_ptr<TClass> w; // Empty weak_ptr
{
std::shared_ptr<TClass> c(new TClass); // TClass: -1
std::weak_ptr<TClass> w1(c); // Construct from shared_ptr
std::weak_ptr<TClass> w; // Empty weak_ptr
w = c;
std::weak_ptr<TClass> w3(w);
w3.reset(); // w3 becomes empty
w3 = w; // w3 points to the TClass as well
std::shared_ptr<TClass> c2 = w.lock(); //Get shared_ptr by weak_ptr
c2->IntValue = 1;
} // ~TClass: 1
std::shared_ptr<TClass> c3 = w.lock(); // c3 is empty shared_ptr
? http://ideone.com/KP8oSL
CYCLIC REFERENCE PROBLEM
class CyclicA {
public:
shared_ptr<CyclicB> b;
};
class CyclicB {
public:
shared_ptr<CyclicA> a;
};
void TestSharedPtrCyclicRef()
{
shared_ptr<CyclicA> a(new CyclicA);
shared_ptr<CyclicB> b(new CyclicB);
a->b = b;
b->a = a;
} // Neither a nor b is deleted
? http://ideone.com/KP8oSL
CYCLIC REFERENCE - FIX
class FixCyclicA {
public:
std::shared_ptr<FixCyclicB> b;
};
class FixCyclicB {
public:
std::weak_ptr<FixCyclicA> a;
};
void TestWeakPtrFixCyclicRef()
{
std::shared_ptr<FixCyclicA> a(new FixCyclicA);
std::shared_ptr<FixCyclicB> b(new FixCyclicB);
a->b = b;
b->a = a;
} // Both a and b are deleted
? How to get shared_ptr from class¡¯s member function?
ENABLE SHARED FROM THIS - WHY
class TShareClass {
...
std::shared_ptr<TShareClass> GetThis() {
// how to achieve?
}
void CallFoo() {
Foo(GetThis());
}
}
void Foo(const std::shared_ptr<TShareClass>& s)
{
// Do something to s, e.g. s->xxx = xxx
}
? A wrong way
ENABLE SHARED FROM THIS ¨C THE
WRONG WAY
class TShareClass {
...
std::shared_ptr<TShareClass> GetThis () {
return std::shared_ptr<TShareClass>(this);
} // This gets deleted after out-of-scope
}
{
std::shared_ptr<TShareClass> a(new TShareClass);
std::shared_ptr<TShareClass> temp = a.GetThis();
} // Deleted twice!
? One way to achieve: Add a weak_ptr
ENABLE SHARED FROM THIS ¨C AN
ATTEMP
class TMyShareClass
{
public:
std::shared_ptr<TMyShareClass> GetThis() {
return MyWeakPtr.lock(); // Make sure MyWeakPtr is valid
}
std::weak_ptr<TMyShareClass> MyWeakPtr;
};
std::shared_ptr<TMyShareClass> c1(new TMyShareClass());
c1->MyWeakPtr = c1;
std::shared_ptr<TMyShareClass> c2 = c1->GetThis();
? C++11¡¯s built-in enable_shared_from_this
? http://ideone.com/wRUj3U
ENABLE SHARED FROM THIS ¨C A
DECENT WAY
class TShareClass : public std::enable_shared_from_this<TShareClass>
{
...
std::shared_ptr<TShareClass> GetThis() {
return shared_from_this();
}
};
std::shared_ptr<TShareClass> c1(new TShareClass());
std::shared_ptr<TShareClass> c2 = c1->GetThis();
? Do not call shared_from_this()from constructor
¨C weak_ptr is not valid yet in ctor
? Always create shared_ptr<T>, never create raw T*
? Consider make ctor/copy-ctors private and unique the
creation
¨C Prevent creating raw T in case of wrong usage
¨C Benefit from perfect forwarding
ENABLE SHARED FROM THIS ¨C BE
CAREFUL
TShareClass* c1 = new TShareClass();
std::shared_ptr<TShareClass> c2 = c1->GetThis();
// Undefined behavior
// Throws exception 'std::bad_weak_ptr¡® on gcc 4.9.x
? Perfect creation of T (http://ideone.com/UyIPgb)
class TPerfectCtor : public std::enable_shared_from_this<TPerfectCtor>
{
private:
TPerfectCtor(int I = -1) = default;
TPerfectCtor(const TPerfectCtor& r) = default;
public:
template<typename ... T>
static std::shared_ptr<TPerfectCtor> Create(T&& ... all) {
return std::shared_ptr<TPerfectCtor>(
new TPerfectCtor(std::forward<T>(all)...));
}
std::shared_ptr<TPerfectCtor> GetThis() {
return shared_from_this();
}
};
// std::shared_ptr<TPerfectCtor> c1(new TPerfectCtor()); // compile error
std::shared_ptr<TPerfectCtor> c1 = TPerfectCtor::Create(); // TPerfectCtor: -1
std::shared_ptr<TPerfectCtor> c2 = TPerfectCtor::Create(2); // TPerfectCtor: 2
c2 = c1->GetThis(); // ~TPerfectCtor: 2
ENABLE SHARED FROM THIS ¨C BEST
PRACTICE
Miscs
? Default, use unique_ptr
? Default, use unique_ptr in containers
¨C std::vector<std::unique_ptr<T>>
? If the object has shared ownership, use shared_ptr
? If the objects have shared ownership, use shared_ptr in
containers
¨C std::vector<std::shared_ptr<T>>
? Prefer to pass by const reference
¨C void Foo(const std::shared_ptr<T>& sp);
¨C void Foo(const std::unique_ptr<T>& up);
Do not write like below
¨C void Foo(std::shared_ptr<T>& sp); // Sometimes compile error
¨C Why? sp.reset(new Base) while sp is Derived
MISCS
MISCS ¨C ARRAY SUPPORT
std::unique_ptr<T[]> ua(new T [5]); // OK
boost::scoped_ptr<T[]> ua(new T [5]); // Compile error
std::shared_ptr<T[]> ua(new T [5]); // Compile error
boost::shared_ptr<T []> a(new T [5]); // OK (since Boost 1.53)
// A custom deleter for array
std::shared_ptr<T> a(new T [5], std::default_delete<T[]>());
// OK, but access with a.get()[index]
// Never pass T[] to shared_ptr<T>
std::shared_ptr<T> a(new T [5]); // Crash
boost::shared_ptr<T> a(new T [5]); // Crash
? Suggested ways to use array in smart pointer
¨C std::unique_ptr<T[]>
¨C std::shared_ptr<T> with custom delete
¨C boost::shared_ptr<T[]> (Since Boost 1.53)
¨C boost::shared_array<T>
? Consider boost::ptr_vector<T> for vector of shared_ptr if
performance is critical
? http://ideone.com/n9lZJ2
MISCS ¨C CONT.
? boost¡¯s Pointer Container Library
¨C ptr_sequence_adapter
? ptr_vector
? ptr_list
? ptr_deque
? ¡­
¨C associative_ptr_container
? ptr_set_adapter
? ptr_multiset_adapter
? ptr_map_adapter
? ¡­
? boost::scoped_array
? boost::intrusive_ptr
FURTHER READINGS
Thank You!

More Related Content

C++11 smart pointer

  • 2. ? Overview ? shared_ptr ? unique_ptr ? weak_ptr ¨C Cyclic reference problem ¨C Enable shared from this ? Miscs AGENDA
  • 3. ? std::shared_ptr ¨C shared ownership ? std::unique_ptr ¨C unique ownership ? std::weak_ptr ¨C No ownership ? NO std::intrusive_ptr OVERVIEW ? boost::shared_ptr ¨C shared ownership ? boost::scoped_ptr ¨C unique ownership ? boost::weak_ptr ¨C No ownership ¡Ö Differences: ? Compiler (C++11 vs C++03) ? Move-Semantic ? std::unique_ptr supports transfer-of-ownership ? boost::scoped_ptr is neither copyable nor movable ? Array support (See details in Miscs)
  • 5. ? Features ¨C share ownership ¨C reference count ¨C auto delete ¨C native inheritance ¨C cast ? Overhead ¨C Manager-Object* ¨C Managed-Object-T* ¨C Lock of increment/decrement of reference count (Thread safe) SHARED_PTR shared_ptr<T> Manager Object* T* Reference Counted with Lock Object T
  • 6. ? Refer to objects allocated with new and can be deleted with delete ? Create by new or make_shared ¨C shared_ptr<T> t(new T(¡­)); ¨C shared_ptr<T> t(make_shared<T>(¡­)); ? Try hard to avoid using raw pointers ¨C Mixing smart and built-in pointers can be hard to get right ? Then never explicitly call delete RULES OF SHARED_PTR
  • 7. ? shared_ptr<T> t(new T(¡­)); ¨C Two dynamic allocations ? shared_ptr<T> t(make_shared<T>(¡­)); ¨C Single dynamic allocation ? Why? ¨C Manager-Object* ¨C Managed-Object-T* ? Prefer ::make_shared if a lof of shared_ptrs are created MAKE_SHARED VS NEW shared_ptr<T> Manager Object* T* Reference Counted with Lock Object T
  • 8. ? http://ideone.com/aEFxlk BASIC USE OF SHARED_PTR std::shared_ptr<TClass> c2(new TClass(2)); // TClass 2 std::shared_ptr<TClass> c3 = std::make_shared<TClass>(3); std::shared_ptr<TClass> c4; // Empty shared_ptr c4.reset(new TClass(4)); // TClass: 4 if (c4) { ... // Do something } c4.reset(); // c4 becomes empty if (c4) { // Now it returns false ... // Code does not go here }
  • 9. ? Same as raw pointer ? http://ideone.com/jp4iCI INHERITANCE OF SHARED_PTR std::shared_ptr<TDerived> dp1(new TDerived); std::shared_ptr<TBase> bp1 = dp1; std::shared_ptr<TBase> bp2(dp1); std::shared_ptr<TBase> bp3(new TDerived);
  • 10. ? Similar with raw pointer ¨C static_pointer_cast ¨C dynamic_pointer_cast ¨C const_pointer_cast ? Create a new shared_ptr! ? http://ideone.com/TdcPDl CASTING SHARED_PTR std::shared_ptr<TBase> bp1(new TDerived); std::shared_ptr<const TBase> cbp(new TBase); std::shared_ptr<TDerived> dp1 = std::static_pointer_cast<TDerived>(bp1); std::shared_ptr<TDerived> dp2 = std::dynamic_pointer_cast<TDerived>(bp1); std::shared_ptr<TBase> bp2 = std::const_pointer_cast<TBase>(cbp); //std::shared_ptr<TDerived> d = static_cast<std::shared_ptr<TDerived>>(bp1); // Compile error
  • 12. ? Features ¨C Unique ownership ? Copy constructor and copy assignment = delete ¨C No reference count ¨C auto delete ¨C native inheritance ¨C No cast, or manually cast ? Overhead ¨C Nothing! ? Rules? ¨C The same as shared_ptr UNIQUE_PTR
  • 13. ? new or std::move (transfer ownership) ? http://ideone.com/bxsFvC BASIC USE OF UNIQUE_PTR std::unique_ptr<TClass> c2(new TClass(2)); std::unique_ptr<TClass> c3; // Empty unique_ptr //c3 = c2; // error: use of deleted function operator=() c3 = std::move(c2); // unique_ptr has to be moved // Now c2 owns nothing // Note that return value of a function is a rvalue std::unique_ptr<TClass> GetATClass() { std::unique_ptr<TClass> c(new TClass(0)); return c; // same as `return std::move(c);` } c3 = GetATClass();
  • 14. ? Same as raw pointer ? http://ideone.com/FhgRi9 INHERITANCE OF UNIQUE_PTR std::unique_ptr<TDerived> dp1(new TDerived); std::unique_ptr<TBase> bp1 = std::move(dp1); std::unique_ptr<TBase> bp2(std::move(bp1)); std::unique_ptr<TBase> bp3(new TDerived);
  • 15. ? Generally, do NOT cast ? Why no native cast? ¨C Cast makes a copy of the pointer ? But I do want to cast unique_ptr? ? http://ideone.com/F8CfIG CAST(MANUALLY) OF UNIQUE_PTR std::unique_ptr<TBase> bp1(new TDerived); std::unique_ptr<TDerived> dp1(static_cast<TDerived*>(bp1.get())); bp1.release(); // Now bp1 owns nothing bp1 = std::move(dp1); // Transfer ownership to bp1 (inheritance) std::unique_ptr<TDerived> dp2(dynamic_cast<TDerived*>(bp1.get())); bp1.release(); // Now bp1 owns nothing
  • 17. ? ¡°Observe¡± the managed object ? Provide a shared_ptr when used ? Why? ¨C Solve cyclic reference of shared_ptr ¨C Helps to get a shared_ptr from ¡°this¡± WEAK_PTR
  • 18. ? http://ideone.com/tZ3ZhJ BASIC USE OF WEAK_PTR std::weak_ptr<TClass> w; // Empty weak_ptr { std::shared_ptr<TClass> c(new TClass); // TClass: -1 std::weak_ptr<TClass> w1(c); // Construct from shared_ptr std::weak_ptr<TClass> w; // Empty weak_ptr w = c; std::weak_ptr<TClass> w3(w); w3.reset(); // w3 becomes empty w3 = w; // w3 points to the TClass as well std::shared_ptr<TClass> c2 = w.lock(); //Get shared_ptr by weak_ptr c2->IntValue = 1; } // ~TClass: 1 std::shared_ptr<TClass> c3 = w.lock(); // c3 is empty shared_ptr
  • 19. ? http://ideone.com/KP8oSL CYCLIC REFERENCE PROBLEM class CyclicA { public: shared_ptr<CyclicB> b; }; class CyclicB { public: shared_ptr<CyclicA> a; }; void TestSharedPtrCyclicRef() { shared_ptr<CyclicA> a(new CyclicA); shared_ptr<CyclicB> b(new CyclicB); a->b = b; b->a = a; } // Neither a nor b is deleted
  • 20. ? http://ideone.com/KP8oSL CYCLIC REFERENCE - FIX class FixCyclicA { public: std::shared_ptr<FixCyclicB> b; }; class FixCyclicB { public: std::weak_ptr<FixCyclicA> a; }; void TestWeakPtrFixCyclicRef() { std::shared_ptr<FixCyclicA> a(new FixCyclicA); std::shared_ptr<FixCyclicB> b(new FixCyclicB); a->b = b; b->a = a; } // Both a and b are deleted
  • 21. ? How to get shared_ptr from class¡¯s member function? ENABLE SHARED FROM THIS - WHY class TShareClass { ... std::shared_ptr<TShareClass> GetThis() { // how to achieve? } void CallFoo() { Foo(GetThis()); } } void Foo(const std::shared_ptr<TShareClass>& s) { // Do something to s, e.g. s->xxx = xxx }
  • 22. ? A wrong way ENABLE SHARED FROM THIS ¨C THE WRONG WAY class TShareClass { ... std::shared_ptr<TShareClass> GetThis () { return std::shared_ptr<TShareClass>(this); } // This gets deleted after out-of-scope } { std::shared_ptr<TShareClass> a(new TShareClass); std::shared_ptr<TShareClass> temp = a.GetThis(); } // Deleted twice!
  • 23. ? One way to achieve: Add a weak_ptr ENABLE SHARED FROM THIS ¨C AN ATTEMP class TMyShareClass { public: std::shared_ptr<TMyShareClass> GetThis() { return MyWeakPtr.lock(); // Make sure MyWeakPtr is valid } std::weak_ptr<TMyShareClass> MyWeakPtr; }; std::shared_ptr<TMyShareClass> c1(new TMyShareClass()); c1->MyWeakPtr = c1; std::shared_ptr<TMyShareClass> c2 = c1->GetThis();
  • 24. ? C++11¡¯s built-in enable_shared_from_this ? http://ideone.com/wRUj3U ENABLE SHARED FROM THIS ¨C A DECENT WAY class TShareClass : public std::enable_shared_from_this<TShareClass> { ... std::shared_ptr<TShareClass> GetThis() { return shared_from_this(); } }; std::shared_ptr<TShareClass> c1(new TShareClass()); std::shared_ptr<TShareClass> c2 = c1->GetThis();
  • 25. ? Do not call shared_from_this()from constructor ¨C weak_ptr is not valid yet in ctor ? Always create shared_ptr<T>, never create raw T* ? Consider make ctor/copy-ctors private and unique the creation ¨C Prevent creating raw T in case of wrong usage ¨C Benefit from perfect forwarding ENABLE SHARED FROM THIS ¨C BE CAREFUL TShareClass* c1 = new TShareClass(); std::shared_ptr<TShareClass> c2 = c1->GetThis(); // Undefined behavior // Throws exception 'std::bad_weak_ptr¡® on gcc 4.9.x
  • 26. ? Perfect creation of T (http://ideone.com/UyIPgb) class TPerfectCtor : public std::enable_shared_from_this<TPerfectCtor> { private: TPerfectCtor(int I = -1) = default; TPerfectCtor(const TPerfectCtor& r) = default; public: template<typename ... T> static std::shared_ptr<TPerfectCtor> Create(T&& ... all) { return std::shared_ptr<TPerfectCtor>( new TPerfectCtor(std::forward<T>(all)...)); } std::shared_ptr<TPerfectCtor> GetThis() { return shared_from_this(); } }; // std::shared_ptr<TPerfectCtor> c1(new TPerfectCtor()); // compile error std::shared_ptr<TPerfectCtor> c1 = TPerfectCtor::Create(); // TPerfectCtor: -1 std::shared_ptr<TPerfectCtor> c2 = TPerfectCtor::Create(2); // TPerfectCtor: 2 c2 = c1->GetThis(); // ~TPerfectCtor: 2 ENABLE SHARED FROM THIS ¨C BEST PRACTICE
  • 27. Miscs
  • 28. ? Default, use unique_ptr ? Default, use unique_ptr in containers ¨C std::vector<std::unique_ptr<T>> ? If the object has shared ownership, use shared_ptr ? If the objects have shared ownership, use shared_ptr in containers ¨C std::vector<std::shared_ptr<T>> ? Prefer to pass by const reference ¨C void Foo(const std::shared_ptr<T>& sp); ¨C void Foo(const std::unique_ptr<T>& up); Do not write like below ¨C void Foo(std::shared_ptr<T>& sp); // Sometimes compile error ¨C Why? sp.reset(new Base) while sp is Derived MISCS
  • 29. MISCS ¨C ARRAY SUPPORT std::unique_ptr<T[]> ua(new T [5]); // OK boost::scoped_ptr<T[]> ua(new T [5]); // Compile error std::shared_ptr<T[]> ua(new T [5]); // Compile error boost::shared_ptr<T []> a(new T [5]); // OK (since Boost 1.53) // A custom deleter for array std::shared_ptr<T> a(new T [5], std::default_delete<T[]>()); // OK, but access with a.get()[index] // Never pass T[] to shared_ptr<T> std::shared_ptr<T> a(new T [5]); // Crash boost::shared_ptr<T> a(new T [5]); // Crash
  • 30. ? Suggested ways to use array in smart pointer ¨C std::unique_ptr<T[]> ¨C std::shared_ptr<T> with custom delete ¨C boost::shared_ptr<T[]> (Since Boost 1.53) ¨C boost::shared_array<T> ? Consider boost::ptr_vector<T> for vector of shared_ptr if performance is critical ? http://ideone.com/n9lZJ2 MISCS ¨C CONT.
  • 31. ? boost¡¯s Pointer Container Library ¨C ptr_sequence_adapter ? ptr_vector ? ptr_list ? ptr_deque ? ¡­ ¨C associative_ptr_container ? ptr_set_adapter ? ptr_multiset_adapter ? ptr_map_adapter ? ¡­ ? boost::scoped_array ? boost::intrusive_ptr FURTHER READINGS