13.1类的声明及定义 成员访问:,->,*,>*,:。其中:主 要用于访问基类或静态成员 构造函数:唯一不能被显式调用成员函 。定义该类的变量或常量时隐式调 用 析构函数:既能被显式调用,也能被隐 式调用。如果程序非正常退出,析构函 数隐式调用可能没机会执行,资源可能 没有释放。隐式调用在函数返回前调 用
3.1 类的声明及定义 成员访问:., ->, .*, ->*, ::。其中::主 要用于访问基类或静态成员。 构造函数:唯一不能被显式调用成员函 数。定义该类的变量或常量时隐式调 用。 析构函数:既能被显式调用,也能被隐 式调用。如果程序非正常退出,析构函 数隐式调用可能没机会执行,资源可能 没有释放。隐式调用在函数返回前调 用
3.1类的声明及定义 exit退出:隐式调用的析构函数不能执行。局部 对象的资源不能被释放,全局对象的资源可以被 释放,即exit退出main后执行收工函数。 abot退出:隐式调用的析构函数不能执行。局 部和全局对象的资源都不能被释放,即abort退出 main后不执行收工函数。 return返回:隐式调用的析构函数得以执行。局 部和全局对象的资源被释放。提倡使用return。 void main(...if (error)return;... n 如果用abot和exit,则要显式调用析构函数。 ·使用异常处理,隐式调用的析构函数会执行
3.1 类的声明及定义 exit退出:隐式调用的析构函数不能执行。局部 对象的资源不能被释放,全局对象的资源可以被 释放,即exit退出main后执行收工函数。 abort退出:隐式调用的析构函数不能执行。局 部和全局对象的资源都不能被释放,即abort退出 main后不执行收工函数。 return返回:隐式调用的析构函数得以执行。局 部和全局对象的资源被释放。提倡使用return。 void main( ){ …; if (error) return; …;} 如果用abort和exit,则要显式调用析构函数。 使用异常处理,隐式调用的析构函数会执行
3.1类的声明及定义 反复析构:同一对象的析构函数被反复 调用。Unix,Windows的内存释放可以反 复进行,但某些资源如设备、文件不能 反复析构。例如,既显式调用又隐式调 用析构函数导致反复析构。 解决方案:对象内部成员设置标志,如 可利用指针是否为空判断内存是否已经 释放。释放完毕立即置空标志
3.1 类的声明及定义 反复析构:同一对象的析构函数被反复 调用。Unix, Windows的内存释放可以反 复进行,但某些资源如设备、文件不能 反复析构。例如,既显式调用又隐式调 用析构函数导致反复析构。 解决方案:对象内部成员设置标志,如 可利用指针是否为空判断内存是否已经 释放。释放完毕立即置空标志
3.1类的声明及定义 【例3.3】定义能防止反复析构的字符串类。 #include <string.h> #include <alloc.h> #include <iostream.h> struct STRING ■ char *s; STRING(char *) ~STRING(); : ■ STRING:STRING(char *t) ■ s=(char *)malloc(strlen(t)+1); strcpy(s,t); cout<<"CONSTRUCT:"<<sj }
3.1 类的声明及定义 【例3.3】定义能防止反复析构的字符串类。 #include <string.h> #include <alloc.h> #include <iostream.h> struct STRING{ char *s; STRING(char *); ~STRING( ); }; STRING::STRING(char *t){ s=(char *)malloc(strlen(t)+1); strcpy(s,t); cout<<"CONSTRUCT: "<<s; }
3.1类的声明及定义 STRING::~STRING( ifs==0)return;//去掉本行,s1析构两次 cout<<"DECONSTRUCT:"<<s; ■ free(s);s=0; //在析构后置析构标志 ■ void main(void) STRING s1("String varible 1\n"); STRING s2("String varible 2\n"); STRING("Constant\n"); cout<<"RETURN\n";
3.1 类的声明及定义 STRING::~STRING( ){ if(s==0) return; //去掉本行,s1析构两次 cout<<"DECONSTRUCT: "<<s; free(s); s=0; //在析构后置析构标志 } void main(void){ STRING s1("String varible 1\n"); STRING s2("String varible 2\n"); STRING("Constant\n"); cout<< "RETURN\n"; }