从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_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等知识就暂且不介绍了