vector的clear()的内部过程与析构函数调用
来源:互联网 发布:java转义字符表 编辑:程序博客网 时间:2024/06/07 13:55
总结一下:
- vector中存储了对象的指针,调用clear后,并不会调用这些指针所指对象析构函数,因此要在clear之前调用delete;
- 如果vector存储的是对象,调用clear后,自建类型的对象(int之类的)直接删除,若是外部类型,则调用析构函数。
class Test { public: Test() { cout<<"Test cons"<<endl;} ~Test() { cout << "Test des" << endl; } }; int main() { vector<Test> vec; Test* p1=new Test(); Test* p2=new Test(); Test* p3=new Test(); vec.push_back(*p1); vec.push_back(*p2); vec.push_back(*p3); //对象如何进行释放,要调用已定义析构函数 vec.clear(); return 0; }
运行结果:
对于这个结果也许你会觉得奇怪,为什么push_back3次,却调用了6次析构函数呢?这个就涉及到vector的构造与内存管理,《STL源码剖析里面》讲得很仔细。
vecor是这样分配内存的:
const size_type len=old_size !=0?2*old_size :1;
也就是说,vector的容量永远是大于或者等于size。而当内存不够的时候,要重新分配空间,于是,allocate(len);再uninititalize_copy();之后再destroy(begin(),end());因此,这其中的内存变化是从1—>2—>4,所以当调用clear时,析构了6次。
下面是从网上摘录的,实际为《STL源码剖析》内容:
// 清除全部元素。注意并未释放空间,以备可能未来还会新加入元素。 void clear() { erase(begin(), end()); } //调用vector::erase的两迭代器范围版本 iterator erase(iterator first, iterator last) { iterator i = copy(last, finish, first); //finish在vector中定义表示目前使用空间的尾,相当于end(),clear调用时last=finish destroy(i, finish); //全局函数,结构的基本函数 finish = finish - (last - first); return first; }
以上关键就是调用了destroy函数。destory函数在<stl_construct.h>
中定义,为了便于分析整个的构造与释放,将construct函数的内容也进行了摘录。这其中要注意的是traits技术。
// destroy()单指针版本 template <class T> inline void destroy(T* pointer) { pointer->~T(); // 唤起 dtor ~T() } // destroy()两迭代器版本 //利用 __type_traits<> 求取最适当措施。 template <class ForwardIterator> inline void destroy(ForwardIterator first, ForwardIterator last) { __destroy(first, last, value_type(first)); } //判断元素的数值型别(value type)有 non-trivial destructor(自定义析构函数) template <class ForwardIterator, class T> inline void __destroy(ForwardIterator first, ForwardIterator last, T*) { typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor; __destroy_aux(first, last, trivial_destructor()); } // 如果元素的数值型别(value type)有 non-trivial destructor(自定义析构函数) template <class ForwardIterator> inline void __destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) { for ( ; first < last; ++first) //遍历元素进行析构 destroy(&*first); //!!!!!关键句!!!!!!!!! } //如果元素的数值型别(value type)有trivial destructor template <class ForwardIterator> inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {} //什么都不做,STL是用了一种保守的方式,只有内建的元素类型(int,float等)进行判定trivial destructor的时候才是__true_type其他一切用户自定义类型都是__false_type // destroy()两迭代器版本,针对char*与wchar_t*的特化版本 inline void destroy(char*, char*) {} inline void destroy(wchar_t*, wchar_t*) {} //仅仅是对placement new 的一层封装 template <class T1, class T2> inline void construct(T1* p, const T2& value) { new (p) T1(value); // placement new; 唤起 ctor T1(value); }
看到这里基本对上述的问题已经有答案了。
由于对象的指针不是内建对象,
for ( ; first < last; ++first) //遍历元素进行析构
destroy(&*first);
*iterator是元素类型,&*iterator是元素地址,也就是一个指针。之后调用&*iterator->~T();所以可知当vector中所存储的元素为对象的时候,调用clear()操作的时候系统会自动调用析构函数。但是当存储元素是指针的时候,指针指向的对象就没法析构了。因此需要释放指针所指对象的话,需要在clear操作之前调用delete。
for(i= 0; i < vItem.size();i++) delete vItem[i];
- vector的clear()的内部过程与析构函数调用
- vector的clear()的内部过程与析构函数调用
- vector的clear操作的内部过程
- vector的clear操作的内部过程
- vector的clear操作的内部过程
- vector的clear操作的内部过程
- vector clear 内部过程
- vector中存储的对象在clear时,会调用对象的析构函数
- C++ vector的delete与clear的区别 - 析构函数
- C++ vector的delete与clear的区别 - 析构函数
- vector::clear(),容器vector的clear函数详解。
- vector的clear()操作与内存
- 过程、函数的定义与调用
- vector的内部实现
- 调用JS函数的内部函数
- vector的clear()和swap()比较
- vector clear 和 swap的比较
- vector::clear ()方法的使用细节
- Android APK反编译就这么简单 详解(附图) .
- spring配置文件详解
- 常用批处理文件命令
- 初学软件工程——(第三章)
- Shell命令——包管理
- vector的clear()的内部过程与析构函数调用
- Socket网络协议简单介绍和使用
- Linux内核之文件系统
- 是什么浪费了我的时间
- C#设置WinForm快捷键(
- mysql的like查询默认是不区分大小写的
- ccf 201503-3 节日
- Shell命令——归档备份
- Shell命令——格式化输出