SlideShare a Scribd company logo
Smart Pointer in C++
韩永泉
2013.9.23
What’s the main/most important characteristic?
Delete the object it points to and release the
resource/memory automatically when the smart
pointer object goes out of its range.
Some kinds of Smart Pointer
 std::auto_ptr<T>
 Deep copy ptr
 Ref counted ptr(intrusive / nonintrusive), such as
boost::shared_ptr, STL/tr1/boost_shared_ptr, self-defined
auto_ptr<T>
Deep Copy Ptr
How to implement a RefCounted SmartPtr class?
Non-intrusive Reference Counter(solution 1)
Non-intrusive Reference Counter(solution 2)
How to implement a RefCounted SmartPtr class?
Intrusive Reference Counter(solution 1)
class RefCountedBase
{
public:
virtual ~RefCountedBase() {}
void addRef() { ++m_refCount; }
void release() { if (--m_refCount == 0) delete this; }
protected:
volatile unsigned int m_refCount;
};
class RealObject : public RefCountedBase
{
public:
……
……
private:
……
};
What does NULL smart pointer like?
What does the smart pointer interface like?
template<class T>
class SmartPtr
{
public:
SmartPtr();
explicit SmartPtr(T *pObj);
SmartPtr(const SmartPtr<T>& other);
SmartPtr<T>& operator=(const SmartPtr<T>& other);
SmartPtr<T>& operator=(T *pObj);
~SmartPtr();
bool operator ! () const; // such as “if (!sp)……”
operator void* () const; // such as “if (sp == NULL/0)……”
// operator bool () const; // not allowed!
T* operator -> ();
const T* operator -> () const;
T& operator * ();
const T& operator * () const;
#ifdef _DEBUG
T* get() const; // DO NOT delete the returned raw pointer!
bool unique() const; // does the current refcount equal to 1?
uint refCount() const;
#endif // _DEBUG
void detach(); // detach current smart pointer from real object, and decrease refcount by 1
void swap(SmartPtr<T>& other); // swap two smart pointers which point to two different objects respectively
private:
T * m_pRealObject;
uint * m_pRefCounter;
};
Some free functions( 智能指针接口的一部分 )
template<class T> inline
bool operator< (const SmartPtr<T>& left, const SmartPtr<T>& right);
template<class T> inline
bool operator==(const SmartPtr<T>& left, const SmartPtr<T>& right);
template<class T> inline
bool operator!=(const SmartPtr<T>& left, const SmartPtr<T>& right);
template<class T> inline
bool operator> (const SmartPtr<T>& left, const SmartPtr<T>& right);
template<class T> inline
bool operator<=(const SmartPtr<T>& left, const SmartPtr<T>& right);
template<class T> inline
bool operator>=(const SmartPtr<T>& left, const SmartPtr<T>& right);
* How to implement them?
template<class T> inline
void swap(SmartPtr<T>& left, SmartPtr<T>& right)
{ left.swap(right); }
Implement some member functions
public:
SmartPtr() : m_pRealObject(NULL), m_pRefCounter(NULL) { }
explicit SmartPtr(T *pObj) {
if (pObj != NULL) {
m_pRefCounter = new uint(1);
m_pRealObject = pObj;
}else {
m_pRefCounter = NULL;
m_pRealObject = NULL;
}
}
SmartPtr(const SmartPtr<T>& other) {
if ( (m_pRealObject = other.m_pRealObject) != NULL) {
m_pRefCounter = other.m_pRefCounter;
++(*m_pRefCounter); /* thread safe ? */
} else { m_pRefCounter = NULL; }
}
~SmartPtr() {
if (m_pRealObject != NULL) {
if (- -(*m_pRefCounter) == 0) /* thread safe ? */
{ delete m_pRefCounter; delete m_pRealObject; }
}
}
bool operator ! () const { (m_pRealObject == NULL) ? true : false; }
T* operator -> () { assert(m_pRealObject != NULL); return m_pRealObject; }
T& operator * () { assert(m_pRealObject != NULL); return (*m_pRealObject); }
……
};
/* ??? */
How to use a RefCounted Smart Pointer class?
• Smart pointer is a class template to
encapsulate a raw pointer (T*) which
points to a real object/variable.
• Provides the same behavior with raw
pointers in object/class manner.
• Share the same one real object
simultaneously among several smart
pointers with the same type.
• Give it a meaningful type name, but
not declare variables directly.
• A smart pointer of base class type can
points to an object of derived class
type.
template<class T> class SmartPtr {
public: ……
private:
T* m_rep; ……
};
typedef SmartPtr<Command> CommandSmartPtr;
CommandSmartPtr cmdPtr(new Command);
cmdPtr->Do(); cmdPtr->ReDo(); cmdPtr->UnDo();
(*cmdPtr).Do; (*cmdPtr).ReDo();
CommandSmartPtr cmdPtr2(cmdPtr);
CommandSmartPtr cmdPtr3; // initialize to NULL
cmdPtr3 = cmdPtr2;
typedef SmartPtr<Command> CommandSmartPtr; (√)
CommandSmartPtr cmdPtrx; (√)
SmartPtr<Command> cmdPtrx; (x)
class Derived : public Base{……};
typedef SmartPtr<Base> BaseSmartPtr;
BaseSmartPtr ptrBase(new Derived);
ptrBase->VirtualFunction();
1
2
3
4
5
Some usages of smart pointer
Singleton pattern
class SomeClass {
public:
~SomeClass();
static SomeClass* get_instance() {
static SomeClass *pOnly = new SomeClass;
return (pOnly);
}
private:
SomeClass();
SomeClass(const SomeClass&);
void operator=(const SomeClass&);
};
typedef SmartPtr<SomeClass> SomeClassSmartPtr;
SomeClassSmartPtr GetSomeClassSingleton() { return SomeClass::get_instance(); }
Function parameter and return value
void SetSomeClass(SomeClassSmartPtr pSomeClassObject);
SomeClassSmartPtr getSomeClass() const;
Global objects
SomeClassSmartPtr g_pSomeClassVariable1(new SomeClass);
static SomeClassSmartPtr gs_pSomeClassVariable2(new SomeClass);
1
2
3
Some usages of SmartPtr
Data Member
SomeClassSmartPtr m_pSomClassObject;
OtherClassSmartPtr m_pOtherClassObject;
STL container element
typedef std::list<SomeClassSmartPtr> SomeClassList;
SomeClassList someObjList;
someObjList.push_back(new SomeClass);
someObjList.push_back(new SomeClass);
someObjList.push_back(new SomeClass);
someObjList.sort();
All other non-copyable classes
Always use it’s smart pointer form anywhere, but not it’s reference/raw pointer/object.
In other design patterns, such as Factory, Command, Observer, etc.
Could you please give some other usages?
5
6
7
8
4
What’s the benefits we can get from it?
Release the resource(memory/device/port,etc.) automatically when there
are none any reference to it; so needn’t remember to release it manually
by any other programmer, especially among different modules
Avoid the overheads of object copy
Don’t lose the polymorphic behavior of real object
Can be used safely in any STL container
?
1
2
3
4
5
Some Notes
• Smart pointer that points to one single object can’t support operator ++, --, [], +n, -n, etc.,
but they are supported by raw pointer;
• Don’t declare the corresponding smart pointer type for an incomplete class like this
class Command; // incomplete class declaration!
typedef SmartPtr<Command> CommandSmartPtr; // Instanciate SmartPtr template for Command?
Because the behavior of the result type ‘CommandSmartPtr’ is possible dependent on the
C++ compiler implementation we are using.
So, the perfect practice is to declare it exactly after the class definition, such as
class Command {
public:
virtual void Do();
……
};
typedef SmartPtr<Command> CommandSmartPtr;
typedef std::set<CommandSmartPtr> CommandList;
……; // all other Command-related types declaration
• If the real object is not created by operator new, how to deal with it?
(1) Specialize the destructor of smart pointer for the real object class;
(2) add a new template parameter as the deleter of the real object, refer to boost::shared_ptr;
• Thread-Safety topic?
Thread-safety of our software/program should not only depend on the smart pointer, because this is not its
responsibility.
1
2
3
4
cyclic pointer
#include <bar.h>
class Foo
{
public:
~Foo() {…}
void AddBar(BarSmartPtr p);
……
private:
BarList m_barList;
};
typedef SmartPtr<Foo> FooSmartPtr;
#include <foo.h> // Is correct? No!
class Foo;
class Bar
{
public:
~Bar() { delete m_pOwner; } // Is correct? No!
void SetOwner(FooSmartPtr p); ; // Is correct? No!
void SetOwner(Foo *p); // OK!
……
private:
FooSmartPtr m_pOwner; // Is correct? No!
Foo *m_pOwner; // loop back, OK!
};
typedef SmartPtr<Bar> BarSmartPtr;
typedef std::list<BarSmartPtr> BarList;
Thread Safety(copy simultaneously)
Thread Safety(destroy simultaneously)
Thread Safety(destroy before copy)
Q&A

More Related Content

PDF
Smart Pointers
PDF
C++11 smart pointer
PPTX
Smart pointers
PDF
Smart Pointers in C++
PPTX
What's New in C++ 11/14?
PDF
Writing Node.js Bindings - General Principles - Gabriel Schulhof
PPTX
Алексей Кутумов, Вектор с нуля
KEY
Objective-Cひとめぐり
Smart Pointers
C++11 smart pointer
Smart pointers
Smart Pointers in C++
What's New in C++ 11/14?
Writing Node.js Bindings - General Principles - Gabriel Schulhof
Алексей Кутумов, Вектор с нуля
Objective-Cひとめぐり

What's hot (20)

PPTX
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
PDF
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
PDF
Welcome to Modern C++
PPTX
Pro typescript.ch03.Object Orientation in TypeScript
PDF
OpenGL ES 3 Reference Card
PDF
Memory Management with Java and C++
PDF
C++11: Rvalue References, Move Semantics, Perfect Forwarding
PDF
PDF
OpenGL ES 3.1 Reference Card
PDF
OpenGL 4.6 Reference Guide
PPTX
Дмитрий Нестерук, Паттерны проектирования в XXI веке
PDF
Oxygine 2 d objects,events,debug and resources
PDF
Vulkan 1.1 Reference Guide
PPT
Memory Management In C++
PDF
glTF 2.0 Reference Guide
PDF
Asterisk: PVS-Studio Takes Up Telephony
PDF
2 + 2 = 5: Monkey-patching CPython with ctypes to conform to Party doctrine
PDF
printf tricks
PDF
Swift で JavaScript 始めませんか? #iOSDC
TXT
Advance C++notes
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
Welcome to Modern C++
Pro typescript.ch03.Object Orientation in TypeScript
OpenGL ES 3 Reference Card
Memory Management with Java and C++
C++11: Rvalue References, Move Semantics, Perfect Forwarding
OpenGL ES 3.1 Reference Card
OpenGL 4.6 Reference Guide
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Oxygine 2 d objects,events,debug and resources
Vulkan 1.1 Reference Guide
Memory Management In C++
glTF 2.0 Reference Guide
Asterisk: PVS-Studio Takes Up Telephony
2 + 2 = 5: Monkey-patching CPython with ctypes to conform to Party doctrine
printf tricks
Swift で JavaScript 始めませんか? #iOSDC
Advance C++notes
Ad

Viewers also liked (11)

PDF
Pointer in c++ part2
PPT
Pointers+(2)
PPTX
intro to pointer C++
PPTX
Intro to C++ Basic
PPTX
Learning C++ - Pointers in c++ 2
PDF
Pointers
PPTX
Pointers in c++
PDF
Pointer in c++ part1
PPTX
Pointers in c++
PPTX
C++ Pointers
PPT
Unit 6 pointers
Pointer in c++ part2
Pointers+(2)
intro to pointer C++
Intro to C++ Basic
Learning C++ - Pointers in c++ 2
Pointers
Pointers in c++
Pointer in c++ part1
Pointers in c++
C++ Pointers
Unit 6 pointers
Ad

Similar to Smart Pointer in C++ (20)

PPTX
Introduction to modern c++ principles(part 1)
PPTX
smart.pptxsmart.pptxsmart.pptxsmart.pptxsmart.pptx
PPT
Beware of Pointers
PDF
smart pointers are unique concept to avoid memory leakage
PPT
C++ Memory Management
PPTX
Pointers Refrences & dynamic memory allocation in C++
PDF
Object Oriented Programming using C++ - Part 4
ODP
C++ Secure Programming
PPTX
pointers.pptx
PDF
Virtual Method Table and accident prevention
PPTX
C++ Class & object pointer in c++ programming language
PPTX
Pointers,virtual functions and polymorphism cpp
PDF
C++ tutorial boost – 2013
PPTX
(Slightly) Smarter Smart Pointers
PDF
C++11 & C++14
PPTX
#OOP_D_ITS - 3rd - Pointer And References
PPTX
Pointers, virtual function and polymorphism
PPTX
Data structure and Algorithms (C++).pptx
PPTX
Pointer and polymorphism
Introduction to modern c++ principles(part 1)
smart.pptxsmart.pptxsmart.pptxsmart.pptxsmart.pptx
Beware of Pointers
smart pointers are unique concept to avoid memory leakage
C++ Memory Management
Pointers Refrences & dynamic memory allocation in C++
Object Oriented Programming using C++ - Part 4
C++ Secure Programming
pointers.pptx
Virtual Method Table and accident prevention
C++ Class & object pointer in c++ programming language
Pointers,virtual functions and polymorphism cpp
C++ tutorial boost – 2013
(Slightly) Smarter Smart Pointers
C++11 & C++14
#OOP_D_ITS - 3rd - Pointer And References
Pointers, virtual function and polymorphism
Data structure and Algorithms (C++).pptx
Pointer and polymorphism

Smart Pointer in C++

  • 1. Smart Pointer in C++ 韩永泉 2013.9.23
  • 2. What’s the main/most important characteristic? Delete the object it points to and release the resource/memory automatically when the smart pointer object goes out of its range.
  • 3. Some kinds of Smart Pointer  std::auto_ptr<T>  Deep copy ptr  Ref counted ptr(intrusive / nonintrusive), such as boost::shared_ptr, STL/tr1/boost_shared_ptr, self-defined
  • 6. How to implement a RefCounted SmartPtr class? Non-intrusive Reference Counter(solution 1) Non-intrusive Reference Counter(solution 2)
  • 7. How to implement a RefCounted SmartPtr class? Intrusive Reference Counter(solution 1) class RefCountedBase { public: virtual ~RefCountedBase() {} void addRef() { ++m_refCount; } void release() { if (--m_refCount == 0) delete this; } protected: volatile unsigned int m_refCount; }; class RealObject : public RefCountedBase { public: …… …… private: …… };
  • 8. What does NULL smart pointer like?
  • 9. What does the smart pointer interface like? template<class T> class SmartPtr { public: SmartPtr(); explicit SmartPtr(T *pObj); SmartPtr(const SmartPtr<T>& other); SmartPtr<T>& operator=(const SmartPtr<T>& other); SmartPtr<T>& operator=(T *pObj); ~SmartPtr(); bool operator ! () const; // such as “if (!sp)……” operator void* () const; // such as “if (sp == NULL/0)……” // operator bool () const; // not allowed! T* operator -> (); const T* operator -> () const; T& operator * (); const T& operator * () const; #ifdef _DEBUG T* get() const; // DO NOT delete the returned raw pointer! bool unique() const; // does the current refcount equal to 1? uint refCount() const; #endif // _DEBUG void detach(); // detach current smart pointer from real object, and decrease refcount by 1 void swap(SmartPtr<T>& other); // swap two smart pointers which point to two different objects respectively private: T * m_pRealObject; uint * m_pRefCounter; };
  • 10. Some free functions( 智能指针接口的一部分 ) template<class T> inline bool operator< (const SmartPtr<T>& left, const SmartPtr<T>& right); template<class T> inline bool operator==(const SmartPtr<T>& left, const SmartPtr<T>& right); template<class T> inline bool operator!=(const SmartPtr<T>& left, const SmartPtr<T>& right); template<class T> inline bool operator> (const SmartPtr<T>& left, const SmartPtr<T>& right); template<class T> inline bool operator<=(const SmartPtr<T>& left, const SmartPtr<T>& right); template<class T> inline bool operator>=(const SmartPtr<T>& left, const SmartPtr<T>& right); * How to implement them? template<class T> inline void swap(SmartPtr<T>& left, SmartPtr<T>& right) { left.swap(right); }
  • 11. Implement some member functions public: SmartPtr() : m_pRealObject(NULL), m_pRefCounter(NULL) { } explicit SmartPtr(T *pObj) { if (pObj != NULL) { m_pRefCounter = new uint(1); m_pRealObject = pObj; }else { m_pRefCounter = NULL; m_pRealObject = NULL; } } SmartPtr(const SmartPtr<T>& other) { if ( (m_pRealObject = other.m_pRealObject) != NULL) { m_pRefCounter = other.m_pRefCounter; ++(*m_pRefCounter); /* thread safe ? */ } else { m_pRefCounter = NULL; } } ~SmartPtr() { if (m_pRealObject != NULL) { if (- -(*m_pRefCounter) == 0) /* thread safe ? */ { delete m_pRefCounter; delete m_pRealObject; } } } bool operator ! () const { (m_pRealObject == NULL) ? true : false; } T* operator -> () { assert(m_pRealObject != NULL); return m_pRealObject; } T& operator * () { assert(m_pRealObject != NULL); return (*m_pRealObject); } …… }; /* ??? */
  • 12. How to use a RefCounted Smart Pointer class? • Smart pointer is a class template to encapsulate a raw pointer (T*) which points to a real object/variable. • Provides the same behavior with raw pointers in object/class manner. • Share the same one real object simultaneously among several smart pointers with the same type. • Give it a meaningful type name, but not declare variables directly. • A smart pointer of base class type can points to an object of derived class type. template<class T> class SmartPtr { public: …… private: T* m_rep; …… }; typedef SmartPtr<Command> CommandSmartPtr; CommandSmartPtr cmdPtr(new Command); cmdPtr->Do(); cmdPtr->ReDo(); cmdPtr->UnDo(); (*cmdPtr).Do; (*cmdPtr).ReDo(); CommandSmartPtr cmdPtr2(cmdPtr); CommandSmartPtr cmdPtr3; // initialize to NULL cmdPtr3 = cmdPtr2; typedef SmartPtr<Command> CommandSmartPtr; (√) CommandSmartPtr cmdPtrx; (√) SmartPtr<Command> cmdPtrx; (x) class Derived : public Base{……}; typedef SmartPtr<Base> BaseSmartPtr; BaseSmartPtr ptrBase(new Derived); ptrBase->VirtualFunction(); 1 2 3 4 5
  • 13. Some usages of smart pointer Singleton pattern class SomeClass { public: ~SomeClass(); static SomeClass* get_instance() { static SomeClass *pOnly = new SomeClass; return (pOnly); } private: SomeClass(); SomeClass(const SomeClass&); void operator=(const SomeClass&); }; typedef SmartPtr<SomeClass> SomeClassSmartPtr; SomeClassSmartPtr GetSomeClassSingleton() { return SomeClass::get_instance(); } Function parameter and return value void SetSomeClass(SomeClassSmartPtr pSomeClassObject); SomeClassSmartPtr getSomeClass() const; Global objects SomeClassSmartPtr g_pSomeClassVariable1(new SomeClass); static SomeClassSmartPtr gs_pSomeClassVariable2(new SomeClass); 1 2 3
  • 14. Some usages of SmartPtr Data Member SomeClassSmartPtr m_pSomClassObject; OtherClassSmartPtr m_pOtherClassObject; STL container element typedef std::list<SomeClassSmartPtr> SomeClassList; SomeClassList someObjList; someObjList.push_back(new SomeClass); someObjList.push_back(new SomeClass); someObjList.push_back(new SomeClass); someObjList.sort(); All other non-copyable classes Always use it’s smart pointer form anywhere, but not it’s reference/raw pointer/object. In other design patterns, such as Factory, Command, Observer, etc. Could you please give some other usages? 5 6 7 8 4
  • 15. What’s the benefits we can get from it? Release the resource(memory/device/port,etc.) automatically when there are none any reference to it; so needn’t remember to release it manually by any other programmer, especially among different modules Avoid the overheads of object copy Don’t lose the polymorphic behavior of real object Can be used safely in any STL container ? 1 2 3 4 5
  • 16. Some Notes • Smart pointer that points to one single object can’t support operator ++, --, [], +n, -n, etc., but they are supported by raw pointer; • Don’t declare the corresponding smart pointer type for an incomplete class like this class Command; // incomplete class declaration! typedef SmartPtr<Command> CommandSmartPtr; // Instanciate SmartPtr template for Command? Because the behavior of the result type ‘CommandSmartPtr’ is possible dependent on the C++ compiler implementation we are using. So, the perfect practice is to declare it exactly after the class definition, such as class Command { public: virtual void Do(); …… }; typedef SmartPtr<Command> CommandSmartPtr; typedef std::set<CommandSmartPtr> CommandList; ……; // all other Command-related types declaration • If the real object is not created by operator new, how to deal with it? (1) Specialize the destructor of smart pointer for the real object class; (2) add a new template parameter as the deleter of the real object, refer to boost::shared_ptr; • Thread-Safety topic? Thread-safety of our software/program should not only depend on the smart pointer, because this is not its responsibility. 1 2 3 4
  • 17. cyclic pointer #include <bar.h> class Foo { public: ~Foo() {…} void AddBar(BarSmartPtr p); …… private: BarList m_barList; }; typedef SmartPtr<Foo> FooSmartPtr; #include <foo.h> // Is correct? No! class Foo; class Bar { public: ~Bar() { delete m_pOwner; } // Is correct? No! void SetOwner(FooSmartPtr p); ; // Is correct? No! void SetOwner(Foo *p); // OK! …… private: FooSmartPtr m_pOwner; // Is correct? No! Foo *m_pOwner; // loop back, OK! }; typedef SmartPtr<Bar> BarSmartPtr; typedef std::list<BarSmartPtr> BarList;
  • 21. Q&A

Editor's Notes