August 7th, 2006 by 张磊
今天在前些日子下载的清华视频课件上看了看C++后面的内容,弄明白了原来拷贝构造函数的浅拷贝和深拷贝就是那个意思(以为多深奥呢)。看到了虚函数那里,谈了虚析构函数,自己心里痒痒,就开了VC,实践了一下。 #include using namespace std; class A{ public: A(){cout< <”Building A..”< ~A(){cout<<”Deleting A..”< }; class B:public A{ public: B(){cout<<”Building B..”< ~B(){cout<<”Deleting B”< }; int main(){ A *a = new B(); delete a; } 这样一段程序的运行结果是: Building A.. Building B.. Deleting A.. 最开始我并不明白倒数第二句”A *a= new B();”是什么意思,现在明白了。a是一个指向数据类型为A的指针,构造它调用的是B的构造函数。由于B是从A继承过来,所以在调用B()之前先调用了A()。但是,当对象析构时,却调用的是A类的析构函数,B类的析构函数没有调用,发生了内存泄漏。造成这种问题的原因是:当A类指针指向的内存单元(即B类对象的数据)被释放时,编译器看到指针类型是A类的,所以调用A类的析构函数。 现在,可以使用虚析构函数来解决问题。将程序中class A的定义作如下修改: class A{ public: A(){cout< <”Building A..”< virtual ~A(){cout<<”Deleting A..”< [...]
July 31st, 2006 by 张磊
前一段看到tinyfool提到《c++primer》,心里一动。自己下载了这本书回来,还从来没仔细看过。从昨天开始,我有空就瞧着这本书,发现里面讲的东西真是好,要是我们的课也用这本书做教材,该学得多深刻阿。 读书的过程中,往往都能让我有更新的理解。下面是一段讲顺序结构容器的: Quote: vector 表示一段连续的内存区域每个元素被顺序存储在这段内存中对vector 的随机访问比如先访问元素5 然后访问15 然后再访问7 等等效率很高因为每次访问离vector起始处的位移都是固定的但是在任意位置而不是在vector 末尾插人元素则效率很低因为它需要把待插入元素右边的每个元素都拷贝一遍类似地删除任意一个而不是vector的最后一个元素效率同样很低因为待删除元素右边的每个元素都必须被复制一遍这种代价对于大型的复杂的类对象来说尤其大一个deque 也表示一段连续的内存区域但是与vector 不同的是它支持高效地在其首部插入和删除元素它通过两级数组结构来实现一级表示实际的容器第二级指向容器的首和尾。 list 表示非连续的内存区域并通过一对指向首尾元素的指针双向链接起来从而允许向前和向后两个方向进行遍历在list 的任意位置插入和删除元素的效率都很高指针必须被重新赋值但是不需要用拷贝元素来实现移动另一方面它对随机访问的支持并不好访问一个元素需要遍历中间的元素另外每个元素还有两个指针的额外空间开销。 下面是选择顺序容器类型的一些准则 如果我们需要随机访问一个容器则vector 要比list 好得多 如果我们已知要存储元素的个数则vector 又是一个比list 好的选择 如果我们需要的不只是在容器两端插入和删除元素则list 显然要比vector 好 除非我们需要在容器首部插入和删除元素否则vector 要比deque 好 如果我们既需要随机访问元素又需要随机插入和删除元素那么又该怎么办呢我们需要在随机访问的代价和拷贝右边或左边相邻元素的代价之间进行折衷一般来说应该是由应用程序的主要操作查找或插入来决定容器类型的选择为了做这个决定我们可能需要知晓两种容器类型的性能如果两种容器类型的性能都不能够使我们满意则需要自己设计更复杂的数据结构 俩字,精辟。如果本看看这本书,真是白学计算机了。