首页 > 代码库 > 从LLVM源码学C++(一)

从LLVM源码学C++(一)

今天开始需要分析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_REFERENCES14   OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}15 16   OwningPtr &operator=(OwningPtr &&Other) {17     reset(Other.take());18     return *this;19   }20 #endif21 22   ~OwningPtr() {23     delete Ptr;24   }25 26   /// reset - Change the current pointee to the specified pointer.  Note that27   /// calling this with any pointer (including a null pointer) deletes the28   /// 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 does37   /// 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等知识就暂且不介绍了