C++ 继承,构造函数,析构函数(下)

简介: C++ 继承,构造函数,析构函数

二.析构函数

创建对象时,系统会为对象分配所需要的内存空间等资源,当程序结束或对象被释放时,系统为对象分配的资源也需要回收,以便可以重新分配给其他对象使用。在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;
};

像这样,父类又有父类(我们可以形象地成为‘爷爷类’),就称为多层继承。

在最后必须要提醒一点:可以使用父类的指针指向子类对象,但最好不要用子类的指针指向父类对象(因为子类对象的属性多于父类,子类指针指向父类元素的话,可能会让指针指向本不属于父类的属性),如果这样做的话,会有安全问题

相关文章
|
4天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
22 4
|
1月前
|
安全 程序员 编译器
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
79 11
|
1月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
53 1
|
1月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
39 1
|
1月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
19 1
|
1月前
|
安全 编译器 程序员
C++的忠实粉丝-继承的热情(1)
C++的忠实粉丝-继承的热情(1)
16 0
|
1月前
|
编译器 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
27 0
|
1月前
|
程序员 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-1
C++入门11——详解C++继承(菱形继承与虚拟继承)-1
32 0
|
1月前
|
C++
C++构造函数初始化类对象
C++构造函数初始化类对象
17 0
|
1月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
20 0