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++职工管理系统(类继承、文件、指针操作、中文乱码解决)
7 0
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
|
4天前
|
C++
【C++】学习笔记——继承_2
【C++】学习笔记——继承_2
11 1
|
6天前
|
编译器 C++
C++中的继承
C++中的继承
13 1
|
1天前
|
存储 编译器 C++
【C++】类和对象④(再谈构造函数:初始化列表,隐式类型转换,缺省值
C++中的隐式类型转换在变量赋值和函数调用中常见,如`double`转`int`。取引用时,须用`const`以防修改临时变量,如`const int& b = a;`。类可以有隐式单参构造,使`A aa2 = 1;`合法,但`explicit`关键字可阻止这种转换。C++11起,成员变量可设默认值,如`int _b1 = 1;`。博客探讨构造函数、初始化列表及编译器优化,关注更多C++特性。
|
2天前
|
存储 编译器 C语言
【C++】类和对象②(类的默认成员函数:构造函数 | 析构函数)
C++类的六大默认成员函数包括构造函数、析构函数、拷贝构造、赋值运算符、取地址重载及const取址。构造函数用于对象初始化,无返回值,名称与类名相同,可重载。若未定义,编译器提供默认无参构造。析构函数负责对象销毁,名字前加`~`,无参数无返回,自动调用以释放资源。一个类只有一个析构函数。两者确保对象生命周期中正确初始化和清理。
|
4天前
|
程序员 编译器 C++
【c++】继承
【c++】继承
6 0
|
4天前
|
安全 Java 程序员
【C++航海王:追寻罗杰的编程之路】继承你学会了么?
【C++航海王:追寻罗杰的编程之路】继承你学会了么?
6 0
|
4天前
|
程序员 编译器 C++
【C++】学习笔记——继承_1
【C++】学习笔记——继承_1
7 0
|
5天前
|
编译器 C语言 C++
【C++】:构造函数和析构函数
【C++】:构造函数和析构函数
14 0
|
2天前
|
C++
【C++】日期类Date(详解)②
- `-=`通过复用`+=`实现,`Date operator-(int day)`则通过创建副本并调用`-=`。 - 前置`++`和后置`++`同样使用重载,类似地,前置`--`和后置`--`也复用了`+=`和`-=1`。 - 比较运算符重载如`&gt;`, `==`, `&lt;`, `&lt;=`, `!=`,通常只需实现两个,其他可通过复合逻辑得出。 - `Date`减`Date`返回天数,通过迭代较小日期直到与较大日期相等,记录步数和符号。 ``` 这是236个字符的摘要,符合240字符以内的要求,涵盖了日期类中运算符重载的主要实现。