析构函数

C++-Record17—构造和析构的基本知识

馋奶兔 提交于 2020-01-29 08:02:19
目录 基本概念 有关构造函数 有关析构函数 案例讲解 构造与析构对函数来说有什么用呢? 总体代码 创建一个对象时,常常需要作某些初始化的工作,例如对数据成员赋初值。注意,类的数据成员是不能在声明类时初始化的。 为了解决这个问题,C++编译器提供了 构造函数 (constructor) 来处理对象的初始化。构造 函数是一种特殊的成员函数,与其他成员函数不同,不需要用户来调用它,而是在建立对象时自动执行。 基本概念 有关构造函数 1、构造函数定义及调用 1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数; 2)构造函数在定义时可以有参数; 3)没有任何返回类型的声明。 2、构造函数的调用 自动调用 :一般情况下C++编译器会自动调用构造函数 手动调用 :在一些情况下则需要手工调用构造函数 有关析构函数 1、析构函数定义及调用 1)C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数 语法:~ClassName() 2)析构函数没有参数也没有任何返回类型的声明 3)析构函数在对象销毁时自动被调用 2、析构函数调用机制 C++编译器自动调用 案例讲解 class Test { public: Test() //无参数 构造函数 { a = 10; //作用完成对属性的初始化工作 p = (char *)malloc(100);

结对编程

一个人想着一个人 提交于 2020-01-28 13:14:19
简介 对伙伴的代码进行审查 合作伙伴: 尉安瑞 伙伴 Coding 参考文章: 谷歌是如何做代码审查的 C++代码审---参考林锐高质量C/C ++ 整天说Code Review重要,你知道应该关注哪些关键点吗? - CSDN博客 一.代码审查表分析 功能模块名称 无环图应用 审查人 Stone 审查日期 2018.4.4  代码名称 DYJ  代码作者 尉安瑞  文件结构 重要性 审查项 结论 头文件和定义文件的名称是否合理? 是    头文件和定义文件的目录结构是否合理? 是    版权和版本声明是否完整? 是  重要 头文件是否使用了 ifndef/define/endif 预处理块? 无  无  头文件中是否只存放“声明”而不存放“定义” 无        程序的版式 重要性 审查项 结论   空行是否得体? 否    代码行内的空格是否得体? 否    长行拆分是否得体? 是    “{” 和 “}” 是否各占一行并且对齐于同一列? 否  重要 一行代码是否只做一件事?如只定义一个变量,只写一条语句。 否  重要 If、for、while、do等语句自占一行,不论执行语句多少都要加 “{}”。 否  重要 在定义变量(或参数)时,是否将修饰符 * 和 & 紧靠变量名?注释是否清晰并且必要? 否  重要 注释是否有错误或者可能导致误解? 无  重要 类结构的public,

C#垃圾回收

柔情痞子 提交于 2020-01-27 05:15:11
CLR垃圾回收器采用代(generation)机制,目前支持0、1、2三代: 新构造添加到堆的对象称为第0代。 经过对第0代的垃圾回收之后,第0代的幸存者被提升至第1代。 经过对第1代的垃圾回收之后,第一代的幸存者被提升至第2代 CLR初始化时,会为每一代选择预算。第0代的预算约为256K,第1代预算约2M,第2代预算约10M。在实际使用过程中,垃圾回收器会用类似启发式算法调整各代的预算。 软件开始运行时,运行时会为每一个Generation预留一块连续的内存(这样说并不严格,但不影响此问题的描述),同时会保持一个指向此内存区域中尚未使用部分的指针P,当需要为对象分配空间时,直接返回P所在的地址,并将P做相应的调整即可 .NET会将对象分成两种情况区别对象,一种是大小小于85000字节的对象,称之为小对象,它就对应于前面描述的一般情况;另外一种是大小在85000之上的对象,称之为大对象。在.NET中,所有大对象都是分配在另外一个 特别的连续内存(LOH, Large Object Heap) 中的,而且,每个大对象在创建时即属于G2,也就是说只有在进行Generation 2的垃圾回收时,才会处理LOH。 而且在对LOH进行垃圾回收时不会压缩内存! 更进一步,LOH上空间的使用方式也很特殊——当分配一个大对象时,运行时会优先尝试在LOH的尾部进行分配,如果尾部空间不足

Python 构造函数、 Python 析构函数、Python 垃圾回收机制

萝らか妹 提交于 2020-01-26 08:09:40
构造函数与析构函数 构造函数: 用于初始化类的内容部状态,Python提供的构造函数式 __init__(); 也就是当该类被实例化的时候就会执行该函数。那么我们就可以把要先初始化的属性放到这个函数里面。如下程序: __init__()方法是可选的,如果不提供,Python 会给出默认的__init__方法 一般数据的获取需要定义的get和set方法 析构函数: 上图中的“__del__”就是一个析构函数了,当使用del 删除对象时,会调用他本身的析构函数,另外当对象在某个作用域中调用完毕,在跳出其作用域的同时析构函数也会被调用一次,这样可以用来释放内存空间。 __del__()也是可选的,如果不提供,则Python 会在后台提供默认析构函数 如果要显式的调用析构函数,可以使用del关键字,方式如下: del对象名 垃圾回收机制 Python 采用垃圾回收机制来清理不再使用的对象;Python 提供gc模块释放 不再使用的对象,Python 采用‘引用计数’ 的算法方式来处理回收, 即:当某个对象在其作用域内不再被其他对象引用的时候,Python 就自动清除对象; Python 的函数collect()可以一次性收集所有待处理的对象(gc.collect()) —————————————————————————分割线—————————————————————————————————

chapter3 异常

耗尽温柔 提交于 2020-01-25 16:20:27
大纲: 1、普通函数异常发生,防止局部资源泄漏 2、构造函数异常发生,防止局部资源泄漏 3、禁止析构函数发生的异常传递到调用者 4、抛出异常、传递参数、调用虚函数差别 5、比较异常传递方式 6、慎用异常规格 1、普通函数异常发生,防止局部资源泄漏 异常处理机制: 没有任何的异常捕获机制,将导致程序的控制权到调用者上,原有程序逻辑将不会被执行。相反,如果有异常捕获机制,我们就可以控制程序的执行逻辑。 局部资源,这里指代指针所指向堆资源。 解决方法: 用对象代替指针,对象的析构函数内释放资源。当函数返回时(正常/异常),函数体内的局部对象确保会调用其析构函数来释放资源。 标准类库中auto_ptr<T>可用来支持上述阐述: 构造函数内,使指针指向堆对象 析构函数内,释放堆对象及其占用空间 借鉴auto_ptr<T>的实现方法,对于任何资源,我们将其关联到一个对象上,析构函数内实现资源的释放。 2、构造函数异常发生,防止局部资源泄漏 构造函数内何时发生异常? 在构造函数内尝试分配内存并初始化对象,内存不够,将引发异常,此时程序的控制权将转至调用构造函数的地方。构造函数没有完全被执行, C++对于不完整的对象,在离开其生存空间时,将不会执行对象的析构函数,资源泄漏发生了。 解决方法: 在构造函数内部捕获到异常,释放资源,在向上传递异常。而不是直接将异常向上传递,一旦向上传递

C++之构造函数、参数列表、析构函数

主宰稳场 提交于 2020-01-25 09:13:25
参考自:https://blog.csdn.net/sunSHINEEzy/article/details/78122485 构造函数之默认构造函数(调用的构造函数不用传递参数) 两种实例化方式都是默认构造函数 构造函数之初始化列表 红字部分即为初始化列表:一个引号,多个参数用逗号隔开,赋值用() 初始化列表特性: 其先于构造函数执行 其只能用于构造函数 其可以同时初始化多个数据成员 【注意】初始化列表的功用:对于类中的静态常量,不能用构造函数来初始化,必须使用初始化列表的方式 拷贝构造函数 拷贝构造函数的特点: 当用户没有定义构造函数时,编译器会自动生成一个默认的拷贝构造函数(构造函数也是如此) 当采用直接初始化或复制初始化实例化对象时,系统会自动调用拷贝构造函数 由于拷贝构造函数的特性,拷贝构造函数不能重载!! 【总结】构造函数总结: 【总结】所有参数带有默认值时,转变成了默认构造函数 【注意】初始化列表是所有构造函数都可以实现的. 析构函数(用于释放系统资源的函数) 定义格式: 析构函数特点: 如果没有自定义的析构函数,则系统自动生成 析构函数在对象销毁时自动调用(与之相对应,构造函数在对象实例化时自动调用) 析构函数没有返回值(构造函数也是如此)、没有参数也不能重载 不允许在()内加任何的参数 【重要知识点】对象的生命历程 【总结】成员函数的分类 成员函数的参数修饰方式

C++基础知识

给你一囗甜甜゛ 提交于 2020-01-23 13:08:01
C++ 基础知识 知识点 列号 说明 1 引言 2 函数与参数 3 异常 4 动态存储空间分配 5 自有数据类型 6 异常类illegalParameterValue 引言 在检查一个程序的时候,我们应该提出如下疑问: 它正确吗? 它容易读懂吗? 它有完善的文档吗? 它容易修改吗? 它在运行时需要多大内存? 它的运行时间有多长? 它的通用性如何?能否不加修改就可以解决更大范围的数据? 它可以直接在多种计算机上编译和运行吗?或者说它需要修改之后才能运行吗? 函数与参数 参数的传递方式一:值传递 程序1-1 求两个整数的和 int sum(int a, int b) { return a + b; } 在上述的函数sum中,a,b就是函数sum的形参(formal parameter),每一个形参都是整型的,如果有这样的调用: z = sum(1,2) 那么,1和2变身分别的对应sum的a和b的实参(actual parameter) 在上述的1-1程序中,形参a和b实际上是传值参数(value parameter)。在运行时,函数sum执行前,把实参复制给形参。复制过程是由形参类型的复制构造函数(copy construstor)来完成的。如果实参和形参的类型不同,必须进行类型转换,把实参转换为形参的类型,当然,前提是这样的类型转换是被允许的。 当调用sum(1,2)时

抛出异常与栈展开(stack unwinding)

独自空忆成欢 提交于 2020-01-22 09:16:01
抛出异常时,将暂停当前函数的执行,开始查找匹配的catch子句。首先检查throw本身是否在try块内部,如果是,检查与该try相关的catch子句,看是否可以处理该异常。如果不能处理,就退出当前函数,并且释放当前函数的内存并销毁局部对象,继续到上层的调用函数中查找,直到找到一个可以处理该异常的catch。这个过程称为栈展开(stack unwinding)。当处理该异常的catch结束之后,紧接着该catch之后的点继续执行。 1. 为局部对象调用析构函数 如上所述,在栈展开的过程中,会释放局部对象所占用的内存并运行类类型局部对象的析构函数。但需要注意的是,如果一个块通过new动态分配内存,并且在释放该资源之前发生异常,该块因异常而退出,那么在栈展开期间不会释放该资源,编译器不会删除该指针,这样就会造成内存泄露。 2. 析构函数应该从不抛出异常 在为某个异常进行栈展开的时候,析构函数如果又抛出自己的未经处理的另一个异常,将会导致调用标准库terminate函数。通常terminate函数将调用abort函数,导致程序的非正常退出。所以析构函数应该从不抛出异常。 3. 异常与构造函数 如果在构造函数对象时发生异常,此时该对象可能只是被部分构造,要保证能够适当的撤销这些已构造的成员。 4. 未捕获的异常将会终止程序 不能不处理异常。如果找不到匹配的catch

C++ primer 笔记(四)

北城余情 提交于 2020-01-21 08:45:49
第15章 object-oriented programming, OOP 面向对象编程 :数据抽象,继承,动态绑定。 通过基类的引用或指针调用虚函数时,发生动态绑定。 除了构造函数之外,任意非 static 成员函数都可以是虚函数。保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。 protected不能被外部访问,但可被派生类访问。 private继承:【Derived对象】不能调用Base中的任何东西;所有继承方式【Derived类】都还能调用Base类中的public和protected的东西(成员函数)。Derived类的Derived则都无法调用。 ----------------------------------------------------------- private继承 基类成员 private成员 public成员 protected成员 内部访问 不可访问 可访问 可访问 对象访问 不可访问 不可访问 不可访问 ------------------------------------------------------------ public继承 基类成员 private成员 public成员 protected成员 内部访问 不可访问 可访问 可访问 对象访问 不可访问 可访问 类定义中可访问,外部不可访问

C++进阶学习一去不复返系列:类和对象(二)

安稳与你 提交于 2020-01-16 13:19:49
篇幅过长会影响心情,紧接前一节, C++进阶学习一去不复返系列:类和对象(一) <= 传送门 。 类构造函数 & 析构函数 构造函数 类的 构造函数 是类的一种特殊的成员函数,它会在 每次创建类的新对象时执行 。 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值 。 默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值。 class Line { public: void setLength( double len ); double getLength( void ); Line(double len); // 这是构造函数:没有返回值,也没有void,与类同名的成员函数。 private: double length; }; //构造函数定义 Line::Line( double len) { cout << "Object is being created, length = " << len << endl; length = len; } 使用初始化列表来初始化字段 初始化列表对析构函数参数列表进行初始化。一个类具有多个字段 需要进行初始化,可以使用初始化列表,在不同的字段之间使用逗号进行分隔: Line::Line( double len, double