示例1:

#include<iostream>
using namespace std;
class CDemo{
public:
~CDemo(){cout<<"destructor"<<endl;}
};
void Func(CDemo obj){
cout<<"func"<<endl;
}
CDemo d1;
CDemo Test(){
cout<<"test"<<endl;
return d1;
} int main(){
CDemo d2;
Func(d2);
Test();
cout<<"after test"<<endl;
}

输出结果:

func
destructor
test
destructor
after test
destructor
destructor

程序工输出destructor四次。第一次是由于Func函数结束时,参数对象obj消亡导致的。第二次是因为:第20行调用Test函数,Test函数的返回值是一个临时对象,该临时对象在函数调用所在的语句结束时就消亡了,因此引发析构函数调用。第三次是main函数结束时d2消亡导致的。第四次是整个程序结束时全局对象d1消亡导致的。

示例2:

#include<iostream>
using namespace std;
class Demo{
int id;
public:
Demo(int i){id=i;cout<<"id="<<id<<"constructed"<<endl;}
~Demo(){cout<<"id="<<id<<"destructed"<<endl;}
};
Demo d1(1);
void Func(){
static Demo d2(2);
Demo d3(3);
cout<<"func"<<endl;
} int main(){
Demo d4(4);
d4=6;
cout<<"main"<<endl;
  {
Demo d5(5);
}
Func();
cout<<"main ends"<<endl;
}

输出结果:

id=1constructed
id=4constructed
id=6constructed
id=6destructed
main
id=5constructed
id=5destructed
id=2constructed
id=3constructed
func
id=3destructed
main ends
id=6destructed
id=2destructed
id=1destructed

要分析程序的输出,首先要看看有没有全局对象。因为全局对象是进入main函数以前就形成的,所以全局对象在main函数开始执行前就会被初始化。本程序第9行定义了全局对象d1,因此d1初始化引发的构造函数调用,导致了第1行的输出结果。

main函数开始执行后,局部对象d4初始化,导致第2行的输出。

第18行,“d4=6;”,6先被自动转化成一个临时对象。这个临时对象的初始化导致第3行的输出。临时对象的值被赋给d4后,这条语句执行完毕,临时对象消亡,因此引发析构函数调用,导致第4行输出。

第21行的d5初始化导致第6行输出。d5的作用域和生存期都只到离它最近的,且将其包含在内的那一对“{}”中的"}"为止,即第22行的"}",因此程序执行到第22行时d5消亡,引发析构函数被调用,输出第7行。

第8行的输出是由于进入Func函数后,执行第11行的静态局部对象d2初始化导致的静态局部对象在函数第一次调用并执行到定义它的语句时初始化,生存期一直持续到整个程序结束,所以即使Func函数调用结束,d2也不会消亡。Func函数中的d3初始化导致了第9行输出。第23行,Func函数调用结束后,d3消亡导致第11行输出。

main函数结束时,其局部变量d4消亡,导致第13行输出。整个程序结束时,全局变量d1和静态局部变量d2消亡,导致最后两行输出。

新标准c++程序设计

转载请注明出处

析构函数的调用------新标准c++程序设计的更多相关文章

  1. 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计

    类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...

  2. 复制构造函数被调用的三种情况------新标准c++程序设计

    1.当用一个对象去初始化同类的另一个对象时,会引发复制构造函数被调用.例如,下面的两条语句都会引发复制构造函数的调用,用以初始化c2. C c2 (c1); C c2=c1; 这两条语句是等价的.注意 ...

  3. 多态实现的原理------新标准c++程序设计

    “多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespac ...

  4. 类型转换构造函数 及使用explicit避免类型自动转换------新标准c++程序设计

    类型转换构造函数:  除复制构造函数外,只有一个参数的构造函数一般可以称作类型转换构造函数,因为这样的构造函数能起到类型自动转换的作用.例如下面的程序: #include<iostream> ...

  5. this指针------新标准c++程序设计

    背景:   c++是在c语言的基础上发展而来的,第一个c++的编译器实际上是将c++程序翻译成c语言程序,然后再用c语言编译器进行编译.c语言没有类的概念,只有结构,函数都是全局函数,没有成员函数.翻 ...

  6. 封闭类------新标准c++程序设计

      封闭类:  一个类的成员变量如果是另一个类的对象,就称之为“成员对象”.包含成员对象的类叫封闭类. #include<iostream> using namespace std; cl ...

  7. string类------新标准c++程序设计

    定义: string类是STL中basic_string模板实例化得到的模板类.其定义如下: typedef basic_string<char>string; 构造函数: string类 ...

  8. 内联函数背景、例子、与普通函数的区别及要注意的地方 ------新标准c++程序设计

    背景: 使用函数能够避免将相同代码重些多次的烦恼,还能减少可执行程序的体积,但也会带来程序运行时间上的开销.函数调用在执行时,首先在栈中为形参和局部变量分配存储空间,然后还要将实参的值复制给形参,接下 ...

  9. 正确处理类的复合关系------新标准c++程序设计

    假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类.狗是有主人的,主人也有狗.假定狗只有一个主人,但一个主人可以有最多10条狗.该如何处理“主人”类和“狗”类的关系呢?下面是 ...

随机推荐

  1. 微信JS-SDK实现自定义分享功能,分享给朋友,分享到朋友圈

    分享出去的内容,可以通过jssdk进行修改. 1.配置jssdk Wx_config.html <?php import("@.ORG.jssdk"); $jssdk = n ...

  2. Rest之路 - Rest架构中的重要概念(二)

    状态无关性 Rest 架构中不维持client,resource and request 的状态,我们通常称 Rest 服务是状态无关的.基于此的优势是为设计Rest架构提供了简便:每一个请求可以被完 ...

  3. mysql数据增删查授权

    一 介绍 MySQL数据操作: DML ======================================================== 在MySQL管理软件中,可以通过SQL语句中的 ...

  4. html5测试总结

    1.因为html5不兼容IE78,所以在PC上使用并非十分光.pc上IE还是占主流 2.html5主要用在移动终端 3.html5短期内因为自身的缺陷,用户体验无法达到原生app的体验.如:html5 ...

  5. Deep Learning 学习笔记(3):Linear Regression 数据的预处理

    为了获得良好的收敛,在进行梯度下降前,我们可以对数据进行预处理. 目标是使得数据大小在同一个数据数量级上,均值为零. 一般将数据放缩到(-1,1)区间, 我们可以对数据进行如下操作: 其中u1是数据的 ...

  6. 「小程序JAVA实战」运行微信官方demo(四)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-04/ 微信官方小程序的demo 介绍 https://mp.weixin.qq.com/cgi-b ...

  7. JSP页面生成验证码功能

    <%@ page language="java" contentType="text/html; charset=UTF-8" import=" ...

  8. android获取mp4视频文件总时长和视频宽高<转>

    android使用 MediaMetadataRetriever 获取视频文件的 总时长 和视频的分辨率. 根据该方式获取视频信息可以看出不仅仅可以获取时长和分辨率,还能获取到其他的一些视频信息,不错 ...

  9. oracle:RETURNING 子句

    RETURNING 自己通常结合DML 语句使用.(INSERT UPDATE DELETE) 使用方法: UPDATE table_name SET expr1 RETURNING column_n ...

  10. pandas读写excel

    import pandas as pd import numpy as np df = pd.read_csv("result.csv") # csv # df = pd.read ...