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

C++入门8 构造函数析构函数顺序|拷贝构造

一,构造函数析构函数

调用顺序

我们先来看下面的代码:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring> 
using namespace std;
class student {
public:char my_name[20];int my_id;student(int a) {my_id = a;cout << "构造函数被调用" <<" 学生id为: "<<my_id <<endl;}~student() {cout<< "析构函数被调用" << " 学生id为: " << my_id << endl;}
};int main() {student a(10);student b(20);cout << endl;return 0;
}

这个代码简单的定义了一个学生类,初始化了构造函数和析构函数,a,b赋予初始值,那么他们析构构建顺序又是怎样的呢

可以看到,先定义的先调用构造函数,同时后调用析构函数,这是为什么呢

因为我们系统变量都是在栈区去定义的,我们的栈是一个先进后出的结构,所以导致了这样的情况出现。

全局变量出现

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring> 
using namespace std;
class student {
public:char my_name[20];int my_id;student(int a) {my_id = a;cout << "构造函数被调用" <<" 学生id为: "<<my_id <<endl;}~student() {cout<< "析构函数被调用" << " 学生id为: " << my_id << endl;}
};student max(100);
int main() {student a(10);student b(20);cout << endl;return 0;
}
student min(1);

这个代码的顺序又是如何呢,min变量又会不会参与我们的调用的,我们看看运行结果便知。

可以看到,min参与了调用,因为全局变量在预编译之后,编译之前便会全部初始化,与他的位置无关。

但因为min在主函数后面,所以打印等操作是不被允许的。

还有一件事,如果我们的全局变量和局部变量命名冲突了又该如何呢

我们遵循局部优先的原则,如果想使用全局变量,需要使用  ::全局域解析符

static

static是静态关键字,使用他可以是变量在需要销毁的时候保留,可以作用在for循环,函数返回值等上,看代码:

int main() {//student a(10);//student b(20);cout << endl;for (int i = 0; i < 10; i++){static student a(10);}return 0;
}

难道就因为我们使用了static关键字,我们每次的循环都需要创建一变a吗。

编译器当然不会这么做,他只会在第一次循环创建,那么他是怎么知道这是第几次创建呢,

我们发现a下面赋值为一,这就是编译器的处理,这个位置叫做标记域,编译器如果发现标记域为一,那就是已经创建过的变量,如果为0,那就是还未创建。

二,拷贝构造

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring> 
using namespace std;class student {
public:char my_name[20];int my_id;student(int a) {my_id = a;cout << "构造函数被调用" << " 学生id为: " << my_id << endl;}student() {my_id = 0;cout << "构造函数被调用" << " 学生id为: " << my_id << endl;}~student() {cout << "析构函数被调用" << " 学生id为: " << my_id << endl;}student(const student& it) :my_id(it.my_id) {cout << "拷贝构造函数被调用" << endl;}void Setvalue(int c) {my_id = c;}
};student func(student c) {c.Setvalue(10);return c;
}int main() {student a(10);student b = func(a); // 使用func函数来创建bcout << endl;return 0;
}

这段代码,我们会输出什么,思考

为什么会有两个拷贝构造函数呢,原因是我们在函数中试图返回一个学生类,我们知道函数返回值存储在eax寄存器中,而这个寄存器大小很小,只有四个字节,我们的学生类远远超过四个字节,所以编译器就需要想办法了,他同样拷贝构造了一个一摸一样的学生类在主函数栈帧空间里,eax存储这个学生类的地址空间,这样就可以正常返回了,也就出现了两个拷贝构造函数调用。

http://www.lryc.cn/news/372764.html

相关文章:

  • 【git使用四】git分支理解与操作(详解)
  • 【docker】如何解决artalk的跨域访问问题
  • MYSQL 索引下推 45讲
  • CentOS7服务器中安装openCV4.8的教程
  • Java课程设计:基于swing的贪吃蛇小游戏
  • 【HarmonyOS】HUAWEI DevEco Studio 下载地址汇总
  • 华为OD刷题C卷 - 每日刷题30(小明找位置,分隔均衡字符串)
  • SOFTS: 时间序列预测的最新模型以及Python使用示例
  • C++ 取近似值
  • 云原生系列之Docker常用命令
  • opencv_GUI
  • FlowUs轻量化AI:趁这波升级专业版,全年无限AI助力笔记产出与二次编写
  • Day 22:2786. 访问数组中的位置使分数最大
  • 理解Es的DSL语法(二):聚合
  • matlab-2-simulink-小白教程-如何绘制电路图进行电路仿真
  • CSS从入门到精通——背景样式
  • 网络编程---Java飞机大战联机
  • 一个简单的Oracle函数
  • word中根据上级设置下级编号
  • 【康复学习--LeetCode每日一题】2786. 访问数组中的位置使分数最大
  • bash和sh区别
  • Git 代码管理规范 !
  • MGRS坐标
  • FreeRTOS简单内核实现4 临界段
  • Scala的字符串插值
  • EasyGBS服务器和终端配置
  • git配置2-不同的代码托管平台配置不同的ssh key
  • 【CT】LeetCode手撕—102. 二叉树的层序遍历
  • Flink 命令行提交、展示和取消作业
  • STM32单片机选型方法