今天开始需要分析clang的源码了,LLVM这个开源的project代码写的很不错的,也算是巩固一下C++的一些基础知识了。
首先是在llvm/ADT/OwningPtr.h中定义了owningptr智能指针的实现:
源码如下:
1 /// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it 2 /// guarantees deletion of the object pointed to, either on destruction of the 3 /// OwningPtr or via an explicit reset(). Once created, ownership of the 4 /// pointee object can be taken away from OwningPtr by using the take method. 5 template<class T> 6 class OwningPtr { 7 OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION; 8 OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION; 9 T *Ptr; 10 public: 11 explicit OwningPtr(T *P = 0) : Ptr(P) {} 12 13 #if LLVM_HAS_RVALUE_REFERENCES 14 OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {} 15 16 OwningPtr &operator=(OwningPtr &&Other) { 17 reset(Other.take()); 18 return *this; 19 } 20 #endif 21 22 ~OwningPtr() { 23 delete Ptr; 24 } 25 26 /// reset - Change the current pointee to the specified pointer. Note that 27 /// calling this with any pointer (including a null pointer) deletes the 28 /// current pointer. 29 void reset(T *P = 0) { 30 if (P == Ptr) return; 31 T *Tmp = Ptr; 32 Ptr = P; 33 delete Tmp; 34 } 35 36 /// take - Reset the owning pointer to null and return its pointer. This does 37 /// not delete the pointer before returning it. 38 T *take() { 39 T *Tmp = Ptr; 40 Ptr = 0; 41 return Tmp; 42 } 43 44 T &operator*() const { 45 assert(Ptr && "Cannot dereference null pointer"); 46 return *Ptr; 47 } 48 49 T *operator->() const { return Ptr; } 50 T *get() const { return Ptr; } 51 LLVM_EXPLICIT operator bool() const { return Ptr != 0; } 52 bool operator!() const { return Ptr == 0; } 53 bool isValid() const { return Ptr != 0; } 54 55 void swap(OwningPtr &RHS) { 56 T *Tmp = RHS.Ptr; 57 RHS.Ptr = Ptr; 58 Ptr = Tmp; 59 } 60 };
涉及知识点:
(一)智能指针:在堆栈上实现对原始指针的控制,对RAII至关重要;类似于垃圾回收机制,智能的回收不需要的使用的指针。
参考:http://msdn.microsoft.com/zh-cn/vstudio/hh279674(v=vs.80).aspx
源码中实现了get、reset等重要的接口函数。
(二)运算符重载:
1、上述源码的第8行当中,重载赋值运算符为何返回引用呢?因为这样返回的值既可以当左值也可以当右值
2、http://blog.csdn.net/zgl_dm/article/details/1767201
(三)不要返回局部变量的引用
在上述源码可以看到,几个重载函数都返回了引用,但是不是局部变量的。
http://blog.sina.com.cn/s/blog_40965d3a0101eaiq.html
一旦局部变量超过作用域释放了资源,使用的时候就会出现问题了。
(四)模板以及explicit等知识就暂且不介绍了