当前位置: 首页 > news >正文

C++ 继承机制中的构造器与析构器

继承机制中构造器和析构器的特性

在构造器与析构器项目中 我们知道C++支持程序员自定义建立或销毁一个对象时自动调用的方法(构造器和析构器)


在没有类继承关系下的类构造器与析构器的运行规则

系统在创建某个类的实例时会第一时间自动调用这个类的 构造器
对象消亡时,析构器自动被调用,用来释放对象占用的空间


在类继承的情况下构造器与析构器的运行规则

基类的构造器将在子类的构造器调用之前被调用这是由于基类必须在子类之前被初始化的原则所导致的 与构造器的情况相反基类的析构器将在子类的最后一条语句执行完毕后才被调用(子类的析构器先调用 基类最后调用)

也就是在类继承关系下,构造器的调用顺序为基类优先,而析构器的调用顺序为子类优先.


类继承构造器

带有参数的构造器声明

class Animal
{
public:
	Animal(string Tsex);//Animal基类的构造函数声明(带一个string类的参数 Tsex)
  	string sex;
}

//Animal基类的构造函数定义(带一个string类的参数 Tsex)
Animal::Animal(string Tsex)
{
	sex = Tsex;//将传入的 构造器的参数 赋值给 类中的string类成员sex
}

//派生自Animal基类的子类monkey 
class monkey :public Animal
{
public:
	void climb();
	monkey(string Tsex);//子类monkey的构造器 也是带有参数的构造器
};

继承机制下的派生自Animal基类和looklike基类的子类monkey的  构造器
monkey::monkey(string Tsex):Animal(Tsex)
{	
	//todo子类构造器中并没有设置参数 子类构造器的参数继承自基类构造器的参数
}

此时monkey构造器在进行调用之前 首先调用了基类Animal的构造器也就是首先读取了基类构造器带的tsex参数 到基类成员string sex中 所以在monkey这个子类继承Animal这个基类的成员时sex已经被构造器初始化赋值

注意:
在子类构造器定义中的: Animal(Tsex)作用是 当调用monkey子类的构造器时以Tsex作为输入参数 ,Animal基类的构造器也将被调用(将输入参数Tsex传递给此构造器)
于是,当建立对象为monkey Monkey("雌性")时 将把对象中的字符串传递给monkey(string Tsex)Animal(string Tsex)构造器中的Tsex赋值动作实际发生在Animal基类方法中


相关代码

class Animal
{
public:

	Animal(string Tsex);

	string sex;
	string name;
	string mouth;
};

//todoAnimal基类的构造函数
Animal::Animal(string Tsex)
{
	sex = Tsex;
}

//todo派生自Animal基类和looklike基类的子类monkey
class monkey :public Animal
{
public:
	void climb();
	monkey(string Tsex);
};


//todo继承机制下的派生自Animal基类和looklike基类的子类monkey的  构造器
monkey::monkey(string Tsex):Animal(Tsex)
{	
}
//当调用monkey派生类的构造器时 以string Tsex作为输入参数 同时Animal基类的构造器也将被调用(Tsex 输入参数将传递给他)
//当我们调用对象monkey monkey("雌性的")时 将把字符串 "雌性的" 传递给 monkey()和Animal()构造器 赋值动作实际发生在Animal()方法里 


void monkey::climb()
{
	cout << "我是一只小皮猴 我是爬树小能手" << endl;
}


int main()
{
	//todo继承机制中的构造器和析构器
	monkey Monkey("雌性的");//子类继承了基类构造器的参数
	Animal ani("基类中的sex");//基类构造器参数被子类继承后仍可以使用

	//当我们调用对象monkey monkey("雌性的")时 将把字符串 "雌性的" 传递给 monkey()和Animal()构造器 赋值动作实际发生在Animal()方法里 
	Monkey.name = "猴子";

	cout << "我是一只" << Monkey.sex << Monkey.name<<endl;

	Monkey.climb();
}

在这里插入图片描述
从程序的运行结果可以得出结论:

构造器也可以带有参数,并且可以是任何参数,这个参数的输入条件是在声明对象时在后方加上括号并在括号中输入与构造中带的输入参数一致的参数


类继承析构器

在销毁某个对象时 ,除了此对象的类析构器会被调用之外,此类的基类的析构器也将被自动调用,些事情编译器会自动替你处理。因为析构器不需要输入参数,所以根本用不着使用:SuperClassMethod(arguments)语法!
与类继承机制下构造器的情况相反,基类的析构器将在子类最后一条语句执行完毕后 才被调用


类继承机制下 基类子类的构造器和析构器的执行流程代码

#include <iostream>
#include <string>


using namespace std;

class Baseclass
{
public:

	Baseclass();//todo基类构造器
  ~Baseclass();//todo基类析构器
	
	void doSomething();//基类方法声明(成员函数)
};


class Subclass :public Baseclass
{
public:
	Subclass();//todo子类构造器
  ~Subclass();//todo子类析构器
};

Baseclass::Baseclass()
{
	cout << "1.已进入基类构造器" << endl;
}

Baseclass::~Baseclass()
{
	cout << "2.已进入基类析构器" << endl;
}

void Baseclass::doSomething()
{
	cout << "3.已进入 基类的成员函数 dosomething " << endl;
}

Subclass::Subclass()
{
	cout << "4.已进入子类构造器" << endl;
}

Subclass::~Subclass()
{
	cout << "5.已进入子类析构器" << endl;
}

int main()
{
	Subclass Sub;
	Sub.doSomething();

	cout<<"执行完毕 已到达程序尾部"<<endl;
	return 0;
	//todo析构器将在main函数即将退出时 进行作用
}

在这里插入图片描述
总结:
基类的构造器将在子类的构造器调用之前被调用这是由于基类必须在子类之前被初始化的原则所导致的
与构造器的情况相反 基类的析构器将在子类的最后一条语句执行完毕后才被调用(子类的析构器先调用 基类最后调用)

析构器将在main函数即将退出时 进行作用

推荐文章

https://www.jianshu.com/p/67e166c11e52

相关文章:

  • C#数组
  • C++ 访问控制
  • ASA842配置内网DNS欺骗测试
  • C++ 覆盖方法与重载方法
  • Ubuntu 12.04 ping 响应慢
  • C++ 静态属性和静态方法
  • C++ this指针与静态属性的关系
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • C++ new和delete动态分配和释放内存
  • C++ 类对象与类指针(静态和动态多态)
  • 第六天 if if…else 三木运算符
  • C++ 虚函数与多态性
  • pb11.2build8949 数据窗口dw limit有关问题
  • VS 监视功能
  • C++ 抽象类
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 0基础学习移动端适配
  • Apache Zeppelin在Apache Trafodion上的可视化
  • C# 免费离线人脸识别 2.0 Demo
  • exif信息对照
  • fetch 从初识到应用
  • interface和setter,getter
  • Javascripit类型转换比较那点事儿,双等号(==)
  • Java知识点总结(JavaIO-打印流)
  • Linux后台研发超实用命令总结
  • Mac转Windows的拯救指南
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • 阿里云前端周刊 - 第 26 期
  • 从零开始的无人驾驶 1
  • 关于springcloud Gateway中的限流
  • 看域名解析域名安全对SEO的影响
  • 扑朔迷离的属性和特性【彻底弄清】
  • 前端路由实现-history
  • 如何使用 JavaScript 解析 URL
  • 使用agvtool更改app version/build
  • 微信小程序开发问题汇总
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • AI算硅基生命吗,为什么?
  • ​虚拟化系列介绍(十)
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (全注解开发)学习Spring-MVC的第三天
  • (转)ORM
  • (转)用.Net的File控件上传文件的解决方案
  • .NET 8.0 中有哪些新的变化?
  • .net framework4与其client profile版本的区别
  • .NET MVC第三章、三种传值方式
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NetCore部署微服务(二)
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .Net环境下的缓存技术介绍
  • @angular/cli项目构建--Dynamic.Form
  • [1] 平面(Plane)图形的生成算法
  • [20171102]视图v$session中process字段含义
  • [3D基础]理解计算机3D图形学中的坐标系变换