二.析构函数
创建对象时,系统会为对象分配所需要的内存空间等资源,当程序结束或对象被释放时,系统为对象分配的资源也需要回收,以便可以重新分配给其他对象使用。在C++中,对象资源的释放通过析构函数来完成。析构函数的作用是在对象被释放之前完成一些清理工作。
析构函数的定义
与构造函数一样,析构函数也是类的特殊成员函数,其定义格式如下:
class 类名 { ~析构函数名称(){ } ... }
关于析构函数的定义,有以下注意事项:
1.析构函数必须与类名相同,在析构函数名称前面添加“~”符号
2.析构函数只能有一个,不能重载
3.不能带任何参数
4.不能带任何返回值
案例
通常情况下,当我们在创建类时,如果有动态申请内存的话,析构函数就显得特别重要了。
析构函数的使用案例如下:
#include <stdio.h> struct Student{ int a; int b; Student(){ } Student(int c,int d){ a = c; b = d; } ~Student(){ } }; void Test(){ Student s1; } int main(){ Test(); return 0; }
三.继承,多层继承,多重继承
在创建类的时候,我们通常会有这样的需求,就是好几个类中都有相同的成员,那么C++帮我们很好的解决了代码重复的问题,所谓继承,就是从“先辈”处获得特性。
在C++中,继承就是在原有类的基础上产生新类,新类会继承原类所有的属性和方法。
基类:
原有的类成为基类或父类
派生类,子类:
新类成为派生类或子类。
派生类同样可以作为基类派生出新类。在多层继承结构中,派生类上一层的基类成为直接基类,各层次的基类成为间接基类。
在C++中,声明一个类继承另一个类的格式如下:
class 派生类名称:继承方式 基类名称{ 派生类成员声明; }
我们来通过一个例子说明:
struct Base{ int name; int age; }; struct Teacher{ int name; int age; int id; } struct Student3{ int name; int age; int id; }
我们可以看到在Teacher类中和Student类中都由name属性和age属性,这时候我们就可以通过继承来减少重复代码:
struct Base{ int name; int age; }; struct Teacher:Base{ int id; }; struct Student3:Base{ int id; };
我们可以通过继承来实现,效果和前面一样,我们可以通过反汇编来查看:
#include <stdio.h> struct Base{ int name; int age; }; struct Teacher0:Base{ int id; }; struct Teacher{ int name; int age; int id; } void Test(){ Teacher t; t.age = 1; t.name = 2; t.id = 3; } int main(){ Test(); return 0; }
我们先通过将成员全部定义在一个类中的方式,来到反汇编查看:
mov dword ptr [ebp-8],1 mov dword ptr [ebp-0Ch],2 mov dword ptr [ebp-4],3
我们再通过函数继承的方式看一下:
#include <stdio.h> struct Base{ int name; int age; }; struct Teacher:Base{ int id; }; void Test(){ Teacher t; t.age = 1; t.name = 2; t.id = 3; } int main(){ Test(); return 0; }
我们继续来到反汇编查看:
mov dword ptr [ebp-8],1 mov dword ptr [ebp-0Ch],2 mov dword ptr [ebp-4],3
我们发现在计算机底层,他俩其实其实都一样。但是在我们使用C++的时候,可以大大减少我们的代码。
上述这种方式我们称为继承,我们来讲讲多重继承,我们直接给出例子,相信大家可以理解:
struct Base1{ int a; int b; }; struct Base2{ int c; int d; }; struct Teacher:Base1,Base2{ int e; int f;
像这种同时继承了两个父元素的,我们称为多重继承。
需要注意的是: 当我们使用继承时,父元素会内的属性会在派生类的前面,比如上面这个多重继承:
struct Teacher{ int a; int b; int c; int d; int e; int f; };
多层继承:
struct Base1{ int a; int b; }; struct Base2:Base1{ int c; int d; }; struct Teacher:Base2{ int e; int f; };
像这样,父类又有父类(我们可以形象地成为‘爷爷类’),就称为多层继承。
在最后必须要提醒一点:可以使用父类的指针指向子类对象,但最好不要用子类的指针指向父类对象(因为子类对象的属性多于父类,子类指针指向父类元素的话,可能会让指针指向本不属于父类的属性),如果这样做的话,会有安全问题