Q1:为上周题目中的Fruit和Apple添加构造函数与析构函数,并在构造函数与析构函数中打印控制台信息,观察构造和析枸调用过程。
在栈区创建Fruit对象,创建时调用了Fruit类的构造函数,销毁时调用Fruit类的析构函数。
在堆区创建Fruit对象,创建时会先分配空间,然后调用Fruit类的构造函数,并把指针传回,控制台只能显示调用构造函数这一步。销毁时会先调用析构函数,然后再释放内存,控制台只能显示调用析构函数这一步。
在堆区创建Apple对象,并用父类指针指向它(upcast),这样构造函数的调用次序依次是父类构造函数、子类构造函数。析构时先调用子类析构函数,再调用父类析构函数。
在栈区创建Apple对象,调用构造函数时,先父类再子类,调用析构函数时,先子类再父类。
Q2:然后为Apple类重载::operator new和 ::operator delete,在控制台打印信息,并观察调用结果。
在栈区创建Fruit对象,创建时调用了Fruit类的构造函数,销毁时调用Fruit类的析构函数。
在堆区创建Fruit对象,创建时会先分配空间,然后调用Fruit类的构造函数,并把指针传回,控制台只能显示调用构造函数这一步。销毁时会先调用析构函数,然后再释放内存,控制台只能显示调用析构函数这一步。
在堆区创建Fruit对象,会调用全局new、delete运算符。
在堆区创建Apple对象,并用父类指针指向它(upcast),会调用Apple类的new、delete运算符。
在堆区创建Apple类数组,大小为5个sizeof(Apple)加上一个指针的大小,且后被创建的对象先被销毁。
在创建时强制调用全局的new运算符,在销毁时由于没有要求强制调用全局delete运算符,Apple类的delete运算符被调用了。为了保持一致性,应该在delete前面也加上::
为了呼应第三周的作业而写的测试代码,首先在堆区创建一个数组,每个元素是一个Fruit类型的指针,大小是5×指针大小,20(32位)或40(64位)。再创建5个Apple类型对象,以父类指针指向它们(upcast),会调用Apple类的new分配空间,父类构造函数,子类构造函数,把指针传回。销毁时先调用子类析构函数,父类析构函数,再销毁内存,最后调用全局delete运算符释放分配给指针数组的空间。