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;
};

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

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

相关文章
|
3月前
|
编译器 C++
【C++】详解C++的继承
【C++】详解C++的继承
|
14天前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
59 30
|
3天前
|
C++
c++继承层次结构实践
这篇文章通过多个示例代码,讲解了C++中继承层次结构的实践应用,包括多态、抽象类引用、基类调用派生类函数,以及基类指针引用派生类对象的情况,并提供了相关的参考链接。
|
28天前
|
C++
C++(二十)继承
本文介绍了C++中的继承特性,包括公有、保护和私有继承,并解释了虚继承的作用。通过示例展示了派生类如何从基类继承属性和方法,并保持自身的独特性。此外,还详细说明了派生类构造函数的语法格式及构造顺序,提供了具体的代码示例帮助理解。
|
2月前
|
编译器 C++
C++的基类和派生类构造函数
基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数,类的构造函数不能被继承。构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。 在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数完成,但是大部分基类都有 private 属性的成员变量,它们在派生类中无法访问,更不能使用派生类的构造函数来初始化。 这种矛盾在C++继承中是普遍存在的,解决这个问题的思路是:在派生类的构造函数中调用基类的构造函数。 下面的例子展示了如何在派生类的构造函数中调用基类的构造函数:
32 1
|
2月前
|
安全 Java 编译器
|
3月前
|
存储 Java 程序员
【c++】继承深度解剖
【c++】继承深度解剖
29 1
|
3月前
|
存储 编译器 数据安全/隐私保护
|
3月前
|
Java C++ 运维
开发与运维函数问题之C++中有哪些继承方式如何解决
开发与运维函数问题之C++中有哪些继承方式如何解决
24 0
|
3月前
|
存储 编译器 C++
C++基础知识(六:继承)
多态是面向对象编程的四大基本原则之一,它让程序能够以统一的接口处理不同的对象类型,从而实现了接口与实现分离,提高了代码的灵活性和复用性。多态主要体现在两个层面:静态多态(编译时多态,如函数重载)和动态多态(运行时多态,主要通过虚函数实现)。