200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Java对象析构_c++之对象构造顺序和销毁(析构函数)

Java对象析构_c++之对象构造顺序和销毁(析构函数)

时间:2022-08-29 21:28:19

相关推荐

Java对象析构_c++之对象构造顺序和销毁(析构函数)

一、对象的构造顺序:

1、对于局部对象:

当程序执行流到达对象的定义语句时进行构造。下面还是用代码来解析这句话:

#include

classTest

{

private:

intmi;

public:

Test(inti)

{

mi=i;

printf("Test(inti)is%d\n",mi);

}

Test(constTest&obj)

{

mi=obj.mi;

printf("Test(constTest&)objis%d\n",mi);

}

};

intmain()

{

inti=0;

Testa1=i;//Test(inti):0

while(i<3)

{

Testa2=++i;//Test(inti):1,2,3

}

if(i<4)

{

Testa=a1;//Test(constTest&objis:0

}

else

{

Testa(100);

}

return0;

}

输出结果:

Test(inti)is0

Test(inti)is1

Test(inti)is2

Test(inti)is3

Test(constTest&obj)is0

这里我们可以看出当程序流执行到相应的构造对象的那条执行语句时,就会调用构造函数(或者拷贝构造函数)。goto语句想必大家不陌生,但是都害怕这玩意,下面我们加入goto语句看看会产生什么现象:

#include

classTest{

private:

intmi;

public:

Test(inti)

{

mi=i;

printf("Test(inti)is%d\n",mi);

}

Test(constTest&obj)

{

mi=obj.mi;

printf("Test(constTest&objis%d\n",mi);

}

};

intmain()

{

inti=0;//Test(inti):0

Testa1=i;

while(i<3)

{

Testa2=++i;//Test(inti):1,2,3

}

gotoend;

if(i<4)

{

Testa=a1;//Test(constTest&)objis:0

}

else

{

Testa(100);

}

end:

return0;

}

输出结果:

Test(inti)is0

Test(inti)is1

Test(inti)is2

Test(inti)is3

从结果我们可以看出从if那条语句就被跳过了,没有执行到,这里这样写的目的是为了引出,当你使用goto语句,把对象给屏蔽了,后面你不能使用这个对象了,不然程序会出现大问题:

#include

classTest{

private:

intmi;

public:

Test(inti)

{

mi=i;

printf("Test(inti)is%d\n",mi);

}

Test(constTest&obj)

{

mi=obj.mi;

printf("Test(constTest&objis%d\n",mi);

}

intgetMi()

{

returnmi;

}

};

intmain()

{

inti=0;//Test(inti):0

Testa1=i;

while(i<3)

{

Testa2=++i;//Test(inti):1,2,3

}

gotoend;

Testa(100);

end:

printf("a.miis%d\n",a.getMi());

return0;

}

输出结果:

tt.cpp:Infunction‘intmain()’:

tt.cpp:32:1:error:jumptolabel‘end’[-fpermissive]

end:

^

tt.cpp:30:6:error:fromhere[-fpermissive]

gotoend;

^

tt.cpp:31:12:error:crossesinitializationof‘Testa’

Testa(100);

^

这里就是上面所说了的,对象被goto语句给屏蔽了,后面就不能使用这个对象来进行操作了。

2、对于堆对象:

当程序执行流到达new语句时创建对象

使用new创建对象将自动触发构造函数的调用

代码演示:

#include

classTest

{

private:

intmi;

public:

Test(inti)

{

mi=i;

printf("Test(inti):%d\n",mi);

}

Test(constTest&obj)

{

mi=obj.mi;

printf("Test(constTest&obj):%d\n",mi);

}

intgetMi()

{

returnmi;

}

};

intmain()

{

inti=0;

Test*a1=newTest(i);//Test(inti):0

while(++i

if(i%2)

newTest(i);//Test(inti):1,3,5,7,9

if(i

newTest(*a1);

else

newTest(100);//Test(inti):100

return0;

}

输出结果:

Test(inti):0

Test(inti):1

Test(inti):3

Test(inti):5

Test(inti):7

Test(inti):9

Test(inti):100

3、对于全局对象:

对象的构造顺序是不确定的

不同的编译器使用不同的规则来确定构造顺序。

同样还是来看代码示例,这里我创建了几个文件:tes1.cpp test2.cpp test3.cpp test4.cpp test.h;他们的内容如下:

test1.cpp:

#include"test.h"

Testt4("t4");

intmain()

{

Testt5("t5");

}

test2.cpp:

#include"test.h"

Testt1("t1");

test3.cpp:

#include"test.h"

Testt2("t2");

test4.cpp:

#include"test.h"

Testt3("t3");

test.h:

#ifndef_TEST_H_

#define_TEST_H_

#include

classTest

{

public:

Test(constchar*s)

{

printf("%s\n",s);

}

};

#endif

最后输出结果:

root@txp-virtual-machine:/home/txp#g++test1.cpptest2.cpptest3.cpptest4.cpp-oput

root@txp-virtual-machine:/home/txp#./put

t4

t1

t2

t3

t5

4、小结:

局部对象的构造顺序依赖程序的执行流

堆对象的构造顺序依赖于new的使用顺序

全局对象的构造顺序是不确定的

二、析构函数:

1、c++的类中可以定义一个特殊的清理函数,叫做析构函数,这个函数的功能与构造函数相反,顾名思义就是销毁的意思了。

2、定义:~ClassName()

析构函数没有参数也没有返回值类型声明

析构函数在对象销毁时自动被调用

代码示例:

#include

classTest

{

intmi;

public:

Test(inti)

{

mi=i;

printf("Test():%d\n",mi);

}

~Test()

{

printf("~Test():%d\n",mi);

}

};

intmain()

{

Testt(1);

Test*pt=newTest(2);

deletept;

return0;

}

输出结果:

Test():1

Test():2

~Test():2

~Test():1

3、析构函数的定义准则:

当类中自定义了构造函数,并且析构函数中使用了系统资源(比如说,内存的申请,文件打开),那么就需要自定义析构函数了。

4、小结:

析构函数是对象销毁时进行处理的特殊函数

析构函数在对象销毁时自动被调用

析构函数是对象释放系统资源的保障

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。