C++学习笔记(七)----向量(vector)的实现

    做了几道zoj的题目,感到基础知识都忘得差不多了,很有必要重新学习,选了两本书,一本是大学时的课本《数据结构(C语言版)》,循序渐进,由浅入深,相信学过数据结构的都看过或者听说过这本书.还有一本是在网上找到的,书名是《数据结构和算法分析 C++描述》,这本书文字比较简练,但其中包含的信息量很大,读起来很有味道,也让人很有激情,很好.

    现在分析一下《数据结构和算法分析 C++描述》中图3-7,3-8的代码,看看能从这段代码中找到哪些需要注意的要点.

代码如下:

 

 1 template <typename Object>
 2 class Vector
 3 {
 4   public:
 5     explicit Vector( int initSize = 0 )
 6       : theSize( initSize ), theCapacity( initSize + SPARE_CAPACITY )
 7       { objects = new Object[ theCapacity ]; }
 8     Vector( const Vector & rhs ) : objects( NULL )
 9       { operator=( rhs ); }
10     ~Vector( )
11       { delete [ ] objects; }
12 
13     const Vector & operator= ( const Vector & rhs )
14     {
15         ifthis != &rhs )
16         {
17             delete [ ] objects;
18             theSize = rhs.size( );
19             theCapacity = rhs.theCapacity;
20 
21             objects = new Object[ capacity( ) ];
22             forint k = 0; k < size( ); k++ )
23                 objects[ k ] = rhs.objects[ k ];
24         }
25         return *this;
26     }
27 
28     void resize( int newSize )
29     {
30         if( newSize > theCapacity )
31             reserve( newSize * 2 + 1 );
32         theSize = newSize;
33     }
34 
35     void reserve( int newCapacity )
36     {
37         if( newCapacity < theSize )
38             return;
39 
40         Object *oldArray = objects;
41 
42         objects = new Object[ newCapacity ];
43         forint k = 0; k < theSize; k++ )
44             objects[ k ] = oldArray[ k ];
45 
46         theCapacity = newCapacity;
47 
48         delete [ ] oldArray;
49     }
50 
51 
52     Object & operator[]( int index )
53       { return objects[ index ]; }
54     const Object & operator[]( int index ) const
55       { return objects[ index ]; }
56 
57     bool empty( ) const
58       { return size( ) == 0; }
59     int size( ) const
60       { return theSize; }
61     int capacity( ) const
62       { return theCapacity; }
63 
64     void push_back( const Object & x )
65     {
66         if( theSize == theCapacity )
67             reserve( 2 * theCapacity + 1 );
68         objects[ theSize++ ] = x;
69     }
70 
71     void pop_back( )
72       { theSize--; }
73 
74     const Object & back ( ) const
75       { return objects[ theSize - 1 ]; }
76 
77     typedef Object * iterator;
78     typedef const Object * const_iterator;
79 
80     iterator begin( )
81       { return &objects[ 0 ]; }
82     const_iterator begin( ) const
83       { return &objects[ 0 ]; }
84     iterator end( )
85       { return &objects[ size( ) ]; }
86     const_iterator end( ) const
87       { return &objects[ size( ) ]; }
88 
89     enum { SPARE_CAPACITY = 16 };
90 
91   private:
92     int theSize;
93     int theCapacity;
94     Object * objects;
95 };

 

    1.第1行,template ['templit]关键字后接模板形参表,表明这里定义的Vector是一个类模板,而不是一个类,Vector<int>才是一个类.函数模板也是一样,它们都只是一个"公式".

    2.第5行,将构造函数声明为explicit [ik'splisit] ,是为了抑制由构造函数定义的隐式转换,如果这里没有explicit,那么下面的语句:

     Vector vec;

     ...

     vec=2;

将是合法的,"="右边的2将被这个不带explicit的构造函数隐式转换为一个Vector类型的临时变量,然后再通过operator=复制给vec.但这可能不是我们想要的结果,为了避免错误,在某些情况下,我们给单形参构造函数加上关键字explicit,这样的话上面的语句就不能编译通过了,vec=2要改为vec=vec(2).关于explicit的更多论述,可以参见《C++ Primer》第12.4.4小节.

    3.第6行,是构造函数的初始化列表.关于构造函数的初始化列表,有两个要点.第一,即使列表为空,没有初始化式,构造函数也会先初始化每个成员再进入函数体,这时初始化的规则与初始化变量相同,由此得知第二个要点:如果类的成员本身是一个没有默认构造函数的类类型,或者成员是const、引用类型,这样的成员必须在构造函数初始化列表中进行初始化.详见《C++ Primer》第12.4.1小节.

    4.第7行和第11行,第7行的new返回一个指向Object类型数组的指针,而通过new关键字分配的存储空间需要通过delete操作将其删除.反之,如果某个对象不是通过new操作动态创建获得的,那么它就不能由delete操作释放,事实上在这些对象的生命期结束之后,编译器会自动释放空间.这两行是一个特例,他们不是动态创建和释放单个对象,而是动态创建和释放数组,所以我们看到第11行使用了"delete []"操作符.

    5.第8行至第26行分别定义了Vector的复制构造函数,析构函数和重载赋值操作符.

    6.第52至55行,这里定义了重载下标操作符的两个版本,由于成员函数的定常性是(即函数名后是否有const关键字)是签名的一部分,因此我们可以使用访问函数的operator[]版本返回const引用,而修改函数版本返回一般引用.

posted on 2011-10-31 14:45  Barryhe  阅读(4316)  评论(7编辑  收藏  举报

导航