WebKit Smart Pointer (RefPtr, PassRefPtr)
CS/C/C++ 2009. 12. 11. 05:52참조 :
1. http://webkit.org/coding/RefPtr.html
2. WebKit Source Code
RefPtr
Simple smart pointer.
생성자 및 소멸자
template <typename T>
RefPtr<T>::RefPtr() : m_ptr(0)
{ }
template <typename T>
RefPtr<T>::RefPtr(T* ptr) : m_ptr(ptr)
{
if (ptr) ptr->ref();
}
template <typename T>
RefPtr<T>::~RefPtr()
{
if (T* ptr = m_ptr) ptr->deref();
}
복사 생성자
template <typename T>
RefPtr<T>::RefPtr(const RefPtr& o) : m_ptr(o.m_ptr)
{
if (T* ptr = m_ptr) ptr->ref();
}
대입 연산자
template <typename T> inline
RefPtr<T>& RefPtr<T>::operator=(T* optr)
{
if (optr)
optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
if (ptr)
ptr->deref();
return *this;
}
template <typename T> inline
RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
{
T* optr = o.get();
if (optr)
optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
if (ptr)
ptr->deref();
return *this;
}
template <typename T> inline
RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
{
T* ptr = m_ptr;
m_ptr = o.releaseRef();
if (ptr)
ptr->deref();
return *this;
}
사용 예
// example, not preferred style
class Document
{
// ...
RefPtr<Title> m_title;
}
void Document::setTitle(Title* title)
{
m_title = title;
}
// example, not preferred style
RefPtr<Node> createSpecialNode()
{
RefPtr<Node> a = new Node;
a->setSpecial(true);
return a;
}
RefPtr<Node> b = createSpecialNode();
PassRefPtr
전달시 Ownership을 포기한다.
Recommended only for function argument and result types, copying arguments into RefPtr local variables.
void derefIfNotNull(T* ptr)
{
if (UNLIKELY(ptr != 0))
ptr->deref();
}
template <typename T>
T* PassRefPtr<T>::releaseRef() const
{
T* tmp = m_ptr;
m_ptr = 0;
return tmp;
}
생성자 및 소멸자
template <typename T>
PassRefPtr<T>::PassRefPtr() : m_ptr(0)
{ }
template <typename T>
PassRefPtr<T>::PassRefPtr(T* ptr) : m_ptr(ptr)
{
if (ptr) ptr->ref();
}
template <typename T>
PassRefPtr<T>::~PassRefPtr()
{
derefIfNotNull<T>(m_ptr);
}
복사 생성자
template <typename T>
PassRefPtr<T>::PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef())
{}
대입 연산자
template <typename T> inline
PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
{
if (optr)
optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
if (ptr)
ptr->deref();
return *this;
}
template <typename T> inline
PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref)
{
T* ptr = m_ptr;
m_ptr = ref.releaseRef();
if (ptr)
ptr->deref();
return *this;
}
사용 예
// example, not preferred style
PassRefPtr<Node> createSpecialNode()
{
PassRefPtr<Node> a = new Node;
a->setSpecial(true);
return a;
}
RefPtr<Node> b = createSpecialNode();
WebKit에서는 모든 경우에 RefPtr을 사용하기를 권장한다. 따라서 위의 경우처럼 ownership을 전달하고자 하는 경우
// example, assuming new Node starts with reference count 0
PassRefPtr<Node> createSpecialNode()
{
RefPtr<Node> a = new Node;
a->setSpecial(true);
return a.release();
}
RefPtr<Node> b = createSpecialNode();
adoptRef
Reference count의 조작 없이 생성된 객체를 전달할 수 있게 한다. PassRefPtr의 friend로 되어있다.
template <typename T>
PassRefPtr<T>::PassRefPtr(T* ptr, bool) : m_ptr(ptr)
{ }
template <typename T> inline PassRefPtr<T> adoptRef(T* p)
{
return PassRefPtr<T>(p, true);
}
사용 예
// preferred style
PassRefPtr<Node> Node::create()
{
return adoptRef(new Node);
}
RefPtr<Node> e = Node::create();
// preferred style
PassRefPtr<Node> createSpecialNode()
{
RefPtr<Node> a = Node::create();
a->setCreated(true);
return a.release();
}
RefPtr<Node> b = createSpecialNode();
OwnPtr, PassOwnPtr
RefPtr, PassRefPtr은 RefCounted에서 상속받은 클래스에만 적용할 수 있는 반면, OwnPtr, PassOwnPtr은 pointer type이나 pointed-to type을 취할 수 있다.
복사 생성자를 보면 인자로 std::auto_ptr을 받는데... 그렇다면 결국 패싱할때 소유권을 넘긴다는 말인데... 흠... 음... 흠... 좀더 살펴 봐야 겠다.
template <typename T>
struct RemovePointer {
typedef T Type;
};
template <typename T>
struct RemovePointer<T*> {
typedef T Type;
};
template <typename T> class OwnPtr : public Noncopyable
{
public:
typedef typename RemovePointer<T>::Type ValueType;
typedef ValueType* PtrType;
// ...
private:
PtrType m_ptr;
};
생성자 및 소멸자
template typename<T> explicit
OwnPtr<T>::OwnPtr(PtrType ptr = 0) : m_ptr(ptr)
{ }
template typename<T>
OwnPtr<T>::~OwnPtr()
{
deleteOwnedPtr(m_ptr);
}
복사 생성자
template typename<T>
OwnPtr<T>::OwnPtr(std::auto_ptr<ValueType> autoPtr) : m_ptr(autoPtr.release())
{ }
대입 연산자
template <typename T> inline
OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o)
{
T* ptr = m_ptr;
m_ptr = o.release();
if (ptr)
deleteOwnedPtr(ptr);
return *this;
}
1. http://webkit.org/coding/RefPtr.html
2. WebKit Source Code
RefPtr
Simple smart pointer.
생성자 및 소멸자
template <typename T>
RefPtr<T>::RefPtr() : m_ptr(0)
{ }
template <typename T>
RefPtr<T>::RefPtr(T* ptr) : m_ptr(ptr)
{
if (ptr) ptr->ref();
}
template <typename T>
RefPtr<T>::~RefPtr()
{
if (T* ptr = m_ptr) ptr->deref();
}
복사 생성자
template <typename T>
RefPtr<T>::RefPtr(const RefPtr& o) : m_ptr(o.m_ptr)
{
if (T* ptr = m_ptr) ptr->ref();
}
대입 연산자
template <typename T> inline
RefPtr<T>& RefPtr<T>::operator=(T* optr)
{
if (optr)
optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
if (ptr)
ptr->deref();
return *this;
}
template <typename T> inline
RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
{
T* optr = o.get();
if (optr)
optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
if (ptr)
ptr->deref();
return *this;
}
template <typename T> inline
RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
{
T* ptr = m_ptr;
m_ptr = o.releaseRef();
if (ptr)
ptr->deref();
return *this;
}
사용 예
// example, not preferred style
class Document
{
// ...
RefPtr<Title> m_title;
}
void Document::setTitle(Title* title)
{
m_title = title;
}
// example, not preferred style
RefPtr<Node> createSpecialNode()
{
RefPtr<Node> a = new Node;
a->setSpecial(true);
return a;
}
RefPtr<Node> b = createSpecialNode();
PassRefPtr
전달시 Ownership을 포기한다.
Recommended only for function argument and result types, copying arguments into RefPtr local variables.
void derefIfNotNull(T* ptr)
{
if (UNLIKELY(ptr != 0))
ptr->deref();
}
template <typename T>
T* PassRefPtr<T>::releaseRef() const
{
T* tmp = m_ptr;
m_ptr = 0;
return tmp;
}
생성자 및 소멸자
template <typename T>
PassRefPtr<T>::PassRefPtr() : m_ptr(0)
{ }
template <typename T>
PassRefPtr<T>::PassRefPtr(T* ptr) : m_ptr(ptr)
{
if (ptr) ptr->ref();
}
template <typename T>
PassRefPtr<T>::~PassRefPtr()
{
derefIfNotNull<T>(m_ptr);
}
복사 생성자
template <typename T>
PassRefPtr<T>::PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef())
{}
대입 연산자
template <typename T> inline
PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
{
if (optr)
optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
if (ptr)
ptr->deref();
return *this;
}
template <typename T> inline
PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref)
{
T* ptr = m_ptr;
m_ptr = ref.releaseRef();
if (ptr)
ptr->deref();
return *this;
}
사용 예
// example, not preferred style
PassRefPtr<Node> createSpecialNode()
{
PassRefPtr<Node> a = new Node;
a->setSpecial(true);
return a;
}
RefPtr<Node> b = createSpecialNode();
WebKit에서는 모든 경우에 RefPtr을 사용하기를 권장한다. 따라서 위의 경우처럼 ownership을 전달하고자 하는 경우
// example, assuming new Node starts with reference count 0
PassRefPtr<Node> createSpecialNode()
{
RefPtr<Node> a = new Node;
a->setSpecial(true);
return a.release();
}
RefPtr<Node> b = createSpecialNode();
adoptRef
Reference count의 조작 없이 생성된 객체를 전달할 수 있게 한다. PassRefPtr의 friend로 되어있다.
template <typename T>
PassRefPtr<T>::PassRefPtr(T* ptr, bool) : m_ptr(ptr)
{ }
template <typename T> inline PassRefPtr<T> adoptRef(T* p)
{
return PassRefPtr<T>(p, true);
}
사용 예
// preferred style
PassRefPtr<Node> Node::create()
{
return adoptRef(new Node);
}
RefPtr<Node> e = Node::create();
// preferred style
PassRefPtr<Node> createSpecialNode()
{
RefPtr<Node> a = Node::create();
a->setCreated(true);
return a.release();
}
RefPtr<Node> b = createSpecialNode();
OwnPtr, PassOwnPtr
RefPtr, PassRefPtr은 RefCounted에서 상속받은 클래스에만 적용할 수 있는 반면, OwnPtr, PassOwnPtr은 pointer type이나 pointed-to type을 취할 수 있다.
복사 생성자를 보면 인자로 std::auto_ptr을 받는데... 그렇다면 결국 패싱할때 소유권을 넘긴다는 말인데... 흠... 음... 흠... 좀더 살펴 봐야 겠다.
template <typename T>
struct RemovePointer {
typedef T Type;
};
template <typename T>
struct RemovePointer<T*> {
typedef T Type;
};
template <typename T> class OwnPtr : public Noncopyable
{
public:
typedef typename RemovePointer<T>::Type ValueType;
typedef ValueType* PtrType;
// ...
private:
PtrType m_ptr;
};
생성자 및 소멸자
template typename<T> explicit
OwnPtr<T>::OwnPtr(PtrType ptr = 0) : m_ptr(ptr)
{ }
template typename<T>
OwnPtr<T>::~OwnPtr()
{
deleteOwnedPtr(m_ptr);
}
복사 생성자
template typename<T>
OwnPtr<T>::OwnPtr(std::auto_ptr<ValueType> autoPtr) : m_ptr(autoPtr.release())
{ }
대입 연산자
template <typename T> inline
OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o)
{
T* ptr = m_ptr;
m_ptr = o.release();
if (ptr)
deleteOwnedPtr(ptr);
return *this;
}