本文共 2122 字,大约阅读时间需要 7 分钟。
本节书摘来自异步社区出版社《C++面向对象高效编程(第2版)》一书中的第4章,第4.3节,作者: 【美】Kayshav Dattatri,更多章节内容可以访问云栖社区“异步社区”公众号查看。
C++面向对象高效编程(第2版)
C++提供类的析构函数专门处理无用单元收集,但是,这并不意味着无用单元收集只发生在析构函数中。实际上,某些其他成员函数也必须考虑无用单元收集。类的析构函数给予对象最后一次机会释放它所获得的所有资源。在退出某作用域之前,由语言自动为在该作用域中创建的自动(基于栈)对象调用析构函数。此时,对象即将被销毁(也就是说,被对象占用的内存即将被系统回收)。一旦析构函数完成,对象将彻底地消失。
删除(使用delete操作符)指向某对象的指针时,将通过该对象调用对象所属类的析构函数。
TPerson *p;p = new TPerson(“12-25-95”); // 在堆上创建一个TPerson类对象// ...delete p; // 这将通过p所指向的对象,调用TPerson类的析构函数```。在析构函数执行完毕后,p所指向的内存被释放。TPerson类的构造函数和析构函数的实现,如下所示:
// 第一个构造函数
TPerson::TPerson(const char birthDate[]) : _ssn(0), _name(0), _birthDate(birthDate), _address(0) { / 构造函数体无代码 / }char Strdup (const char src) // 辅助函数{ char* ptr = new char[strlen(src)+1]; strcpy(ptr, src); return ptr;}// 第二个构造函数TPerson::TPerson(const char theName[], const char theAddress[], unsigned long theSSN, const char theBirthDate[]) : _ssn(theSSN), _birthDate(theBirthDate){ // 初始化_name、_address等 _name = (theName ? Strdup(theName) : 0); _address = (theAddress ? Strdup(theAddress) : 0);}`
我们已在堆(heap)上为待储存人名中的字符分配内存。析构函数负责释放这些内存。 // 析构函数TPerson::~TPerson(){ delete [] _name; delete [] _address;}```现在,考虑下面一段代码:
main()
{ TPerson john(“11-23-45”); // ... john.SetName(“John Wayne”);}`
对象john只有出生日期,没有姓名。接下来,我们使用SetName成员函数设置john的姓名。SetName成员函数用来做什么?以下是它的实现代码: void TPerson::SetName(const char newName[]){ unsigned oldLength = _name ? strlen(_name) : 0; unsigned newLength = newName ? strlen(newName) : 0; if (oldLength < newLength) { // _name中没有足够的空间 delete [] _name; // 无用单元收集 // 使用已定义的Strdup函数 _name = (newName ? Strdup(newName) : 0); } else { if (newName) strcpy(_name, newName); else {delete [] _name; _name = 0;} }}```我们检查_name中的字符个数是否足够容纳newName,如果不够就删除_name并分配一块新内存。在分配新内存之前,一定要记得释放_name中的存储区,这非常重要。这就是我们所说的生存期内获得资源。对象john的析构函数仍将正常工作,因为_name确保指向有效内存或者为0。回顾TCar类的例子,当销毁TCar类的对象时,该对象中的对象_owner怎么办?幸运地是,语言提供了帮助。当TCar类对象即将被销毁时,语言将调用包含在TCar类对象中的对象_owner(TPerson类型)的析构函数,确保不会发生资源泄漏。一般而言,在对象即将被销毁时,包含在该对象中的所有对象的析构函数将被递归地调用,直至所有被包含的对象都被销毁。这只适用于按值包含在其他对象中的对象。如果某对象包含指向其他对象的指针,则由析构函数负责显式销毁它们。
转载地址:http://hlnax.baihongyu.com/