Java对象析构_c++之对象构造顺序和销毁(析构函数)
一、对象的构造顺序:
1、对于局部对象:
当程序执行流到达对象的定义语句时进行构造。下面还是用代码来解析这句话:
#include
class Test
{
private:
int mi;
public:
Test(int i)
{
mi=i;
printf("Test(int i) is %d\n",mi);
}
Test(const Test& obj)
{
mi=obj.mi;
printf("Test(const Test&) obj is %d\n",mi);
}
};
int main()
{
int i = 0 ;
Test a1 =i;//Test(int i):0
while(i<3)
{
Test a2 = ++i;//Test(int i):1,2,3
}
if(i<4)
{
Test a = a1; //Test(const Test& obj is :0
}
else
{
Test a(100);
}
return 0;
}
输出结果:
Test(int i) is 0
Test(int i) is 1
Test(int i) is 2
Test(int i) is 3
Test(const Test& obj) is 0
这里我们可以看出当程序流执行到相应的构造对象的那条执行语句时,就会调用构造函数(或者拷贝构造函数)。goto语句想必大家不陌生,但是都害怕这玩意,下面我们加入goto语句看看会产生什么现象:
#include
class Test{
private:
int mi;
public:
Test(int i)
{
mi=i;
printf("Test(int i) is %d\n",mi);
}
Test(const Test& obj)
{
mi=obj.mi;
printf("Test(const Test& obj is %d\n",mi);
}
};
int main()
{
int i = 0; //Test(int i) :0
Test a1 = i;
while( i <3)
{
Test a2 = ++i; //Test(int i) :1,2,3
}
goto end;
if(i <4)
{
Test a = a1;//Test(const Test&) obj is :0
}
else
{
Test a(100);
}
end:
return 0;
}
输出结果:
Test(int i) is 0
Test(int i) is 1
Test(int i) is 2
Test(int i) is 3
从结果我们可以看出从if那条语句就被跳过了,没有执行到,这里这样写的目的是为了引出,当你使用goto语句,把对象给屏蔽了,后面你不能使用这个对象了,不然程序会出现大问题:
#include
class Test{
private:
int mi;
public:
Test(int i)
{
mi=i;
printf("Test(int i) is %d\n",mi);
}
Test(const Test& obj)
{
mi=obj.mi;
printf("Test(const Test& obj is %d\n",mi);
}
int getMi()
{
return mi;
}
};
int main()
{
int i = 0; //Test(int i) :0
Test a1 = i;
while( i <3)
{
Test a2 = ++i; //Test(int i) :1,2,3
}
goto end;
Test a(100);
end:
printf("a.mi is %d\n",a.getMi());
return 0;
}
输出结果:
tt.cpp: In function ‘int main()’:
tt.cpp:32:1: error: jump to label ‘end’ [-fpermissive]
end:
^
tt.cpp:30:6: error: from here [-fpermissive]
goto end;
^
tt.cpp:31:12: error: crosses initialization of ‘Test a’
Test a(100);
^
这里就是上面所说了的,对象被goto语句给屏蔽了,后面就不能使用这个对象来进行操作了。
2、对于堆对象:
当程序执行流到达new语句时创建对象
使用new创建对象将自动触发构造函数的调用
代码演示:
#include
class Test
{
private:
int mi;
public:
Test(int i)
{
mi = i;
printf("Test(int i): %d\n", mi);
}
Test(const Test& obj)
{
mi = obj.mi;
printf("Test(const Test& obj): %d\n", mi);
}
int getMi()
{
return mi;
}
};
int main()
{
int i = 0;
Test* a1 = new Test(i); // Test(int i): 0
while( ++i
if( i % 2 )
new Test(i); // Test(int i): 1, 3, 5, 7, 9
if( i
new Test(*a1);
else
new Test(100); // Test(int i): 100
return 0;
}
输出结果:
Test(int i): 0
Test(int i): 1
Test(int i): 3
Test(int i): 5
Test(int i): 7
Test(int i): 9
Test(int i): 100
3、对于全局对象:
对象的构造顺序是不确定的
不同的编译器使用不同的规则来确定构造顺序。
同样还是来看代码示例,这里我创建了几个文件:tes1.cpp test2.cpp test3.cpp test4.cpp test.h;他们的内容如下:
test1.cpp:
#include "test.h"
Test t4("t4");
int main()
{
Test t5("t5");
}
test2.cpp:
#include "test.h"
Test t1("t1");
test3.cpp:
#include "test.h"
Test t2("t2");
test4.cpp:
#include "test.h"
Test t3("t3");
test.h:
#ifndef _TEST_H_
#define _TEST_H_
#include
class Test
{
public:
Test(const char* s)
{
printf("%s\n", s);
}
};
#endif
最后输出结果:
root@txp-virtual-machine:/home/txp# g++ test1.cpp test2.cpp test3.cpp test4.cpp -o put
root@txp-virtual-machine:/home/txp# ./put
t4
t1
t2
t3
t5
4、小结:
局部对象的构造顺序依赖程序的执行流
堆对象的构造顺序依赖于new的使用顺序
全局对象的构造顺序是不确定的
二、析构函数:
1、c++的类中可以定义一个特殊的清理函数,叫做析构函数,这个函数的功能与构造函数相反,顾名思义就是销毁的意思了。
2、定义:~ClassName()
析构函数没有参数也没有返回值类型声明
析构函数在对象销毁时自动被调用
代码示例:
#include
class Test
{
int mi;
public:
Test(int i)
{
mi = i;
printf("Test(): %d\n", mi);
}
~Test()
{
printf("~Test(): %d\n", mi);
}
};
int main()
{
Test t(1);
Test* pt = new Test(2);
delete pt;
return 0;
}
输出结果:
Test(): 1
Test(): 2
~Test(): 2
~Test(): 1
3、析构函数的定义准则:
当类中自定义了构造函数,并且析构函数中使用了系统资源(比如说,内存的申请,文件打开),那么就需要自定义析构函数了。
4、小结:
析构函数是对象销毁时进行处理的特殊函数
析构函数在对象销毁时自动被调用
析构函数是对象释放系统资源的保障
Java对象析构_c++之对象构造顺序和销毁(析构函数)相关推荐
- C++中对象的构造顺序和析构顺序
文章目录 1 C++中单个对象的构造和析构顺序 1.1 单个对象的构造和析构顺序 2 C++中多个对象的构造和析构顺序 2.1 局部对象的构造顺序 2.2 堆对象的构造顺序 2.3 全局对象的构造顺序 ...
- 【C++深度剖析教程1】C++中的经典问题解析-c++中的对象的构造顺序与析构顺序
c++中的对象的构造顺序与析构顺序 问题一 当程序中存在多个对象时,如何确定这些对象的析构顺序? 一.单个函数创建时构造函数的调用顺序 1.调用父类的构造过程 2.调用成员变量的构造函数(调用顺序与声 ...
- $emit传递多个参数_10年架构师深解java核心技术:方法参数+对象构造,确定不学?...
方法参数 首先回顾一下在程序设计语言中有关参数传递给方法(或函数)的一些专业术语.值调用(call by value)表示方法接收的是调用者提供的值.而引用调用(call by reference)表 ...
- Java构造器、静态对象、非静态对象等的初始化顺序
Java创建类对象时对于构造器,静态对象.非静态对象的初始化有一定的顺序,我简单归纳一下: class classes {public classes(String n) {System.out.pr ...
- 10.C++-构造函数初始化列表、类const成员、对象构造顺序、析构函数
首先回忆下,以前学的const 单独使用const修饰变量时,是定义的常量,比如:const int i=1; 使用volatile const修饰变量时,定义的是只读变量 使用const & ...
- Java I/O中的对象序列化
Java I/O中的对象序列化 Java对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够以后将这个字节序列完全恢复为原来的对象.利用对象的序列化,可以实现轻量级持久性 ...
- java对象生命周期_Java对象生命周期和类生命周期
原标题:Java对象生命周期和类生命周期 作者:彭空空 链接:https://www.jianshu.com/p/25ea857ba78b 导读 对象的生命周期 类的加载机制 类的生命周期 类加载器 ...
- java学习(类和对象)
1.今日导师双选,排名靠前但被拒三次.意难平. 2.简历还在投递中,面试时更注重本科项目经历. 3.研究生阶段,计算机学术?代码能力?哪个重要? 4.循环<可能否>,期待变强... 一.简 ...
- Java笔记07——类和对象
目录 1. 面向对象---概述 1.1 啥是面向对象编程? 1.2 为什么要面向对象编程 1.3 面向对象学什么? 总结一 2 创建和设计 类 2.1 什么是 类? 2.2 什么是对象? 2.3 如何 ...
最新文章
- python tkinter 实现一个秒表 从0开始_Writeathon:从0开始实现的一个side project
- Unity 2D游戏开发快速入门(内部资料)
- Vue axios 上传图片
- 第四范式天枢入选毕马威首届“领先消费科技50”榜单
- system.setin_Java System类setIn()方法及示例
- 干货!这可能是最全的IntelliJ IDEA For Mac快捷键说明,建议收藏!
- 小程序点击获取循环列表中的内容
- 5G 十项全能、搭载麒麟 820 芯片,1899 元起的荣耀 X10 来了!
- Windows 10安装Adobe XD出现白屏闪退问题
- R包ggalluvial绘制冲击图(alluvial diagram)
- iphone6 因为充电线电压不稳,产生的错乱现象
- LocalDateTime和时间戳互转
- HDMI Type A、B、C、D接口图
- 营收和盈利均超市场预期 美光科技的疲软期已画上句号?
- c# forbidden.html,nginx静态资源文件无法访问,403 forbidden错误
- 使用Syncthing搭建自己的私人网盘
- STM32用IIC实现EEPROM的读写
- 【uni-app】只支持在微信小程序运行的 导入外部3d模型
- Cinema 4D R20 Essential Training: VFX Cinema 4D R20基本训练:视觉特效 Lynda课程中文字幕
- GDUT - 专题学习1 A - Red and Black