在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
做了几道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 if( this != &rhs ) 16 { 17 delete [ ] objects; 18 theSize = rhs.size( ); 19 theCapacity = rhs.theCapacity; 20 21 objects = new Object[ capacity( ) ]; 22 for( int 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 for( int 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=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引用,而修改函数版本返回一般引用. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论