今天我同事问我,析构函数里什么都不写,那要它来干什么呢?咋一想似乎是没什么作用哦,就是一个空函数而已。后来想一想不对。下面请让我细细道来。
首先说一下对象的生命周期。对象在声明或new时被创建,在离开作用域时被销毁。在创建时,调用自身的构造函数;在销毁时调用析构函数。
所以有时候会有这样的错误的认识:对象是调用构造函数创建的,在调用析构函数时被销毁的。这种想法也就是前文提到的。
实际上,对象创建的过程是这样的:
1.根据类的大小分配一块内存
2.调用构造函数对这块内存进行初期化
对象销毁的过程是这样的:
1.调用析构函数执行清理工作
2.销毁内存
所以对象创建与构造函数无关,对象销毁时与析构函数无关(假设,构造函数与析构函数都承诺不抛出异常)。
为了验证上面所述来看一个例子。
1 using namespace std; 2 #include <iostream> 3 4 class Foo{ 5 public: 6 Foo(){ 7 cout << &(*this) << endl; 8 } 9 ~Foo(){ 10 } 11 void PrintHello(){ 12 cout<< "hello"<<endl; 13 } 14 }; 15 void main(){ 16 17 Foo foo; 18 foo.~Foo(); 19 foo.PrintHello(); 20 21 }
第7行的输出结果是“C6F7AF”,而PrintHello函数的调用仍然是可以的。
补充一下构造函数和析构函数的特点(摘自互联网)。
构造函数
(1)构造方法的方法名必须与类名相同。
(2)构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。
(3)构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域。
(4)构造方法不能由编程人员调用,而要系统调用。
(5)一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造器,这个构造器不执行任何代码。
(6)构造方法可以重载,以参数的个数,类型,或排列顺序区分
析构函数析构函数(destructor)也是一种成员函数,但它的作用与构造函数相反,
用来在系统释放对象前做一些清理工作,如利用delete运算符释放临时分配的内存,
清零某些内存单元等.当一个对象生存期结束时,系统会自动调用该对象所属类的析构函数;
构造函数的名称与类名相同,而析构函数的名称必须在类名前加上"~"符号;
注意,构造函数和析构函数不能指定任何返回值类型,包括void返回类型;